mirror of
https://github.com/grishka/NearDrop.git
synced 2026-04-03 01:36:15 +02:00
An experimental share extension to send files and too much refactoring
closes #4
This commit is contained in:
47
NearbyShare/Data+Extensions.swift
Normal file
47
NearbyShare/Data+Extensions.swift
Normal file
@@ -0,0 +1,47 @@
|
||||
//
|
||||
// Data+URLSafeBase64.swift
|
||||
// NearDrop
|
||||
//
|
||||
// Created by Grishka on 08.04.2023.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import CoreFoundation
|
||||
|
||||
extension Data{
|
||||
func urlSafeBase64EncodedString() -> String {
|
||||
return String(base64EncodedString().replacingOccurrences(of: "=", with: "").map {
|
||||
if $0=="/"{
|
||||
return "_"
|
||||
} else if $0=="+" {
|
||||
return "-"
|
||||
} else {
|
||||
return $0
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
static func randomData(length: Int) -> Data{
|
||||
var data=Data(count: length)
|
||||
data.withUnsafeMutableBytes {
|
||||
guard 0 == SecRandomCopyBytes(kSecRandomDefault, length, $0.baseAddress!) else { fatalError() }
|
||||
}
|
||||
return data
|
||||
}
|
||||
|
||||
static func dataFromUrlSafeBase64(_ str:String)->Data?{
|
||||
var regularB64=String(str.map{
|
||||
if $0=="_"{
|
||||
return "/"
|
||||
}else if $0=="-"{
|
||||
return "+"
|
||||
}else{
|
||||
return $0
|
||||
}
|
||||
})
|
||||
while (regularB64.count%4) != 0{
|
||||
regularB64=regularB64+"="
|
||||
}
|
||||
return Data(base64Encoded: regularB64, options: .ignoreUnknownCharacters)
|
||||
}
|
||||
}
|
||||
3
NearbyShare/GenerateProtobuf.sh
Executable file
3
NearbyShare/GenerateProtobuf.sh
Executable file
@@ -0,0 +1,3 @@
|
||||
#!/bin/bash
|
||||
|
||||
ls ProtobufSource | xargs protoc --swift_out=Protobuf --proto_path=ProtobufSource
|
||||
353
NearbyShare/InboundNearbyConnection.swift
Normal file
353
NearbyShare/InboundNearbyConnection.swift
Normal file
@@ -0,0 +1,353 @@
|
||||
//
|
||||
// InboundNearbyConnection.swift
|
||||
// NearDrop
|
||||
//
|
||||
// Created by Grishka on 08.04.2023.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Network
|
||||
import CryptoKit
|
||||
import CommonCrypto
|
||||
import System
|
||||
|
||||
import SwiftECC
|
||||
import BigInt
|
||||
|
||||
class InboundNearbyConnection: NearbyConnection{
|
||||
|
||||
private var currentState:State = .initial
|
||||
public var delegate:InboundNearbyConnectionDelegate?
|
||||
private var cipherCommitment:Data?
|
||||
|
||||
enum State{
|
||||
case initial, receivedConnectionRequest, sentUkeyServerInit, receivedUkeyClientFinish, sentConnectionResponse, sentPairedKeyResult, receivedPairedKeyResult, waitingForUserConsent, receivingFiles, disconnected
|
||||
}
|
||||
|
||||
override init(connection: NWConnection, id:String) {
|
||||
super.init(connection: connection, id: id)
|
||||
}
|
||||
|
||||
override func handleConnectionClosure() {
|
||||
super.handleConnectionClosure()
|
||||
currentState = .disconnected
|
||||
do{
|
||||
try deletePartiallyReceivedFiles()
|
||||
}catch{
|
||||
print("Error deleting partially received files: \(error)")
|
||||
}
|
||||
DispatchQueue.main.async {
|
||||
self.delegate?.connectionWasTerminated(connection: self, error: self.lastError)
|
||||
}
|
||||
}
|
||||
|
||||
override internal func processReceivedFrame(frameData:Data){
|
||||
do{
|
||||
switch currentState {
|
||||
case .initial:
|
||||
let frame=try Location_Nearby_Connections_OfflineFrame(serializedData: frameData)
|
||||
try processConnectionRequestFrame(frame)
|
||||
case .receivedConnectionRequest:
|
||||
let msg=try Securegcm_Ukey2Message(serializedData: frameData)
|
||||
ukeyClientInitMsgData=frameData
|
||||
try processUkey2ClientInit(msg)
|
||||
case .sentUkeyServerInit:
|
||||
let msg=try Securegcm_Ukey2Message(serializedData: frameData)
|
||||
try processUkey2ClientFinish(msg, raw: frameData)
|
||||
case .receivedUkeyClientFinish:
|
||||
let frame=try Location_Nearby_Connections_OfflineFrame(serializedData: frameData)
|
||||
try processConnectionResponseFrame(frame)
|
||||
default:
|
||||
let smsg=try Securemessage_SecureMessage(serializedData: frameData)
|
||||
try decryptAndProcessReceivedSecureMessage(smsg)
|
||||
}
|
||||
}catch{
|
||||
lastError=error
|
||||
print("Deserialization error: \(error) in state \(currentState)")
|
||||
#if !DEBUG
|
||||
protocolError()
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
override internal func processTransferSetupFrame(_ frame:Sharing_Nearby_Frame) throws{
|
||||
if frame.hasV1 && frame.v1.hasType, case .cancel = frame.v1.type {
|
||||
print("Transfer canceled")
|
||||
try sendDisconnectionAndDisconnect()
|
||||
return
|
||||
}
|
||||
switch currentState{
|
||||
case .sentConnectionResponse:
|
||||
try processPairedKeyEncryptionFrame(frame)
|
||||
case .sentPairedKeyResult:
|
||||
try processPairedKeyResultFrame(frame)
|
||||
case .receivedPairedKeyResult:
|
||||
try processIntroductionFrame(frame)
|
||||
default:
|
||||
print("Unexpected connection state in processTransferSetupFrame: \(currentState)")
|
||||
print(frame)
|
||||
}
|
||||
}
|
||||
|
||||
override func isServer() -> Bool {
|
||||
return true
|
||||
}
|
||||
|
||||
override func processFileChunk(frame: Location_Nearby_Connections_PayloadTransferFrame) throws{
|
||||
let id=frame.payloadHeader.id
|
||||
guard let fileInfo=transferredFiles[id] else { throw NearbyError.protocolError("File payload ID \(id) is not known") }
|
||||
let currentOffset=fileInfo.bytesTransferred
|
||||
guard frame.payloadChunk.offset==currentOffset else { throw NearbyError.protocolError("Invalid offset into file \(frame.payloadChunk.offset), expected \(currentOffset)") }
|
||||
guard currentOffset+Int64(frame.payloadChunk.body.count)<=fileInfo.meta.size else { throw NearbyError.protocolError("Transferred file size exceeds previously specified value") }
|
||||
if frame.payloadChunk.body.count>0{
|
||||
try fileInfo.fileHandle?.write(contentsOf: frame.payloadChunk.body)
|
||||
transferredFiles[id]!.bytesTransferred+=Int64(frame.payloadChunk.body.count)
|
||||
fileInfo.progress?.completedUnitCount=transferredFiles[id]!.bytesTransferred
|
||||
}else if (frame.payloadChunk.flags & 1)==1{
|
||||
try fileInfo.fileHandle?.close()
|
||||
transferredFiles[id]!.fileHandle=nil
|
||||
fileInfo.progress?.unpublish()
|
||||
transferredFiles.removeValue(forKey: id)
|
||||
if transferredFiles.isEmpty{
|
||||
try sendDisconnectionAndDisconnect()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func processConnectionRequestFrame(_ frame:Location_Nearby_Connections_OfflineFrame) throws{
|
||||
guard frame.hasV1 && frame.v1.hasConnectionRequest && frame.v1.connectionRequest.hasEndpointInfo else { throw NearbyError.requiredFieldMissing }
|
||||
guard case .connectionRequest = frame.v1.type else { throw NearbyError.protocolError("Unexpected frame type \(frame.v1.type)") }
|
||||
let endpointInfo=frame.v1.connectionRequest.endpointInfo
|
||||
guard endpointInfo.count>17 else { throw NearbyError.protocolError("Endpoint info too short") }
|
||||
let deviceNameLength=Int(endpointInfo[17])
|
||||
guard endpointInfo.count>=deviceNameLength+18 else { throw NearbyError.protocolError("Endpoint info too short to contain the device name") }
|
||||
guard let deviceName=String(data: endpointInfo[18..<(18+deviceNameLength)], encoding: .utf8) else { throw NearbyError.protocolError("Device name is not valid UTF-8") }
|
||||
let rawDeviceType:Int=Int(endpointInfo[0] & 7) >> 1
|
||||
remoteDeviceInfo=RemoteDeviceInfo(name: deviceName, type: RemoteDeviceInfo.DeviceType.fromRawValue(value: rawDeviceType))
|
||||
currentState = .receivedConnectionRequest
|
||||
}
|
||||
|
||||
private func processUkey2ClientInit(_ msg:Securegcm_Ukey2Message) throws{
|
||||
guard msg.hasMessageType, msg.hasMessageData else { throw NearbyError.requiredFieldMissing }
|
||||
guard case .clientInit = msg.messageType else{
|
||||
sendUkey2Alert(type: .badMessageType)
|
||||
throw NearbyError.ukey2
|
||||
}
|
||||
let clientInit:Securegcm_Ukey2ClientInit
|
||||
do{
|
||||
clientInit=try Securegcm_Ukey2ClientInit(serializedData: msg.messageData)
|
||||
}catch{
|
||||
sendUkey2Alert(type: .badMessageData)
|
||||
throw NearbyError.ukey2
|
||||
}
|
||||
guard clientInit.version==1 else{
|
||||
sendUkey2Alert(type: .badVersion)
|
||||
throw NearbyError.ukey2
|
||||
}
|
||||
guard clientInit.random.count==32 else{
|
||||
sendUkey2Alert(type: .badRandom)
|
||||
throw NearbyError.ukey2
|
||||
}
|
||||
var found=false
|
||||
for commitment in clientInit.cipherCommitments{
|
||||
if case .p256Sha512 = commitment.handshakeCipher{
|
||||
found=true
|
||||
cipherCommitment=commitment.commitment
|
||||
break
|
||||
}
|
||||
}
|
||||
guard found else{
|
||||
sendUkey2Alert(type: .badHandshakeCipher)
|
||||
throw NearbyError.ukey2
|
||||
}
|
||||
guard clientInit.nextProtocol=="AES_256_CBC-HMAC_SHA256" else{
|
||||
sendUkey2Alert(type: .badNextProtocol)
|
||||
throw NearbyError.ukey2
|
||||
}
|
||||
|
||||
let domain=Domain.instance(curve: .EC256r1)
|
||||
let (pubKey, privKey)=domain.makeKeyPair()
|
||||
publicKey=pubKey
|
||||
privateKey=privKey
|
||||
|
||||
var serverInit=Securegcm_Ukey2ServerInit()
|
||||
serverInit.version=1
|
||||
serverInit.random=Data.randomData(length: 32)
|
||||
serverInit.handshakeCipher = .p256Sha512
|
||||
|
||||
var pkey=Securemessage_GenericPublicKey()
|
||||
pkey.type = .ecP256
|
||||
pkey.ecP256PublicKey=Securemessage_EcP256PublicKey()
|
||||
pkey.ecP256PublicKey.x=Data(pubKey.w.x.asSignedBytes())
|
||||
pkey.ecP256PublicKey.y=Data(pubKey.w.y.asSignedBytes())
|
||||
serverInit.publicKey=try pkey.serializedData()
|
||||
|
||||
var serverInitMsg=Securegcm_Ukey2Message()
|
||||
serverInitMsg.messageType = .serverInit
|
||||
serverInitMsg.messageData=try serverInit.serializedData()
|
||||
let serverInitData=try serverInitMsg.serializedData()
|
||||
ukeyServerInitMsgData=serverInitData
|
||||
sendFrameAsync(serverInitData)
|
||||
currentState = .sentUkeyServerInit
|
||||
}
|
||||
|
||||
private func processUkey2ClientFinish(_ msg:Securegcm_Ukey2Message, raw:Data) throws{
|
||||
guard msg.hasMessageType, msg.hasMessageData else { throw NearbyError.requiredFieldMissing }
|
||||
guard case .clientFinish = msg.messageType else { throw NearbyError.ukey2 }
|
||||
|
||||
var sha=SHA512()
|
||||
sha.update(data: raw)
|
||||
guard cipherCommitment==Data(sha.finalize()) else { throw NearbyError.ukey2 }
|
||||
|
||||
let clientFinish=try Securegcm_Ukey2ClientFinished(serializedData: msg.messageData)
|
||||
guard clientFinish.hasPublicKey else {throw NearbyError.requiredFieldMissing }
|
||||
let clientKey=try Securemessage_GenericPublicKey(serializedData: clientFinish.publicKey)
|
||||
|
||||
try finalizeKeyExchange(peerKey: clientKey)
|
||||
|
||||
currentState = .receivedUkeyClientFinish
|
||||
}
|
||||
|
||||
private func processConnectionResponseFrame(_ frame:Location_Nearby_Connections_OfflineFrame) throws{
|
||||
guard frame.hasV1, frame.v1.hasType else { throw NearbyError.requiredFieldMissing }
|
||||
if case .connectionResponse = frame.v1.type {
|
||||
var resp=Location_Nearby_Connections_OfflineFrame()
|
||||
resp.version = .v1
|
||||
resp.v1=Location_Nearby_Connections_V1Frame()
|
||||
resp.v1.type = .connectionResponse
|
||||
resp.v1.connectionResponse=Location_Nearby_Connections_ConnectionResponseFrame()
|
||||
resp.v1.connectionResponse.response = .accept
|
||||
resp.v1.connectionResponse.status=0
|
||||
resp.v1.connectionResponse.osInfo=Location_Nearby_Connections_OsInfo()
|
||||
resp.v1.connectionResponse.osInfo.type = .apple
|
||||
sendFrameAsync(try resp.serializedData())
|
||||
|
||||
encryptionDone=true
|
||||
|
||||
var pairedEncryption=Sharing_Nearby_Frame()
|
||||
pairedEncryption.version = .v1
|
||||
pairedEncryption.v1=Sharing_Nearby_V1Frame()
|
||||
pairedEncryption.v1.type = .pairedKeyEncryption
|
||||
pairedEncryption.v1.pairedKeyEncryption=Sharing_Nearby_PairedKeyEncryptionFrame()
|
||||
// Presumably used for all the phone number stuff that no one needs anyway
|
||||
pairedEncryption.v1.pairedKeyEncryption.secretIDHash=Data.randomData(length: 6)
|
||||
pairedEncryption.v1.pairedKeyEncryption.signedData=Data.randomData(length: 72)
|
||||
try sendTransferSetupFrame(pairedEncryption)
|
||||
currentState = .sentConnectionResponse
|
||||
} else {
|
||||
print("Unhandled offline frame plaintext: \(frame)")
|
||||
}
|
||||
}
|
||||
|
||||
private func processPairedKeyEncryptionFrame(_ frame:Sharing_Nearby_Frame) throws{
|
||||
guard frame.hasV1, frame.v1.hasPairedKeyEncryption else { throw NearbyError.requiredFieldMissing }
|
||||
var pairedResult=Sharing_Nearby_Frame()
|
||||
pairedResult.version = .v1
|
||||
pairedResult.v1=Sharing_Nearby_V1Frame()
|
||||
pairedResult.v1.type = .pairedKeyResult
|
||||
pairedResult.v1.pairedKeyResult=Sharing_Nearby_PairedKeyResultFrame()
|
||||
pairedResult.v1.pairedKeyResult.status = .unable
|
||||
try sendTransferSetupFrame(pairedResult)
|
||||
currentState = .sentPairedKeyResult
|
||||
}
|
||||
|
||||
private func processPairedKeyResultFrame(_ frame:Sharing_Nearby_Frame) throws{
|
||||
guard frame.hasV1, frame.v1.hasPairedKeyResult else { throw NearbyError.requiredFieldMissing }
|
||||
currentState = .receivedPairedKeyResult
|
||||
}
|
||||
|
||||
private func processIntroductionFrame(_ frame:Sharing_Nearby_Frame) throws{
|
||||
guard frame.hasV1, frame.v1.hasIntroduction else { throw NearbyError.requiredFieldMissing }
|
||||
currentState = .waitingForUserConsent
|
||||
let downloadsDirectory=(try FileManager.default.url(for: .downloadsDirectory, in: .userDomainMask, appropriateFor: nil, create: true)).resolvingSymlinksInPath()
|
||||
for file in frame.v1.introduction.fileMetadata{
|
||||
var dest=downloadsDirectory.appendingPathComponent(file.name)
|
||||
if FileManager.default.fileExists(atPath: dest.path){
|
||||
var counter=1
|
||||
var path:String
|
||||
let ext=dest.pathExtension
|
||||
let baseUrl=dest.deletingPathExtension()
|
||||
repeat{
|
||||
path="\(baseUrl.path) (\(counter))"
|
||||
if !ext.isEmpty{
|
||||
path+=".\(ext)"
|
||||
}
|
||||
counter+=1
|
||||
}while FileManager.default.fileExists(atPath: path)
|
||||
dest=URL(fileURLWithPath: path)
|
||||
}
|
||||
let info=InternalFileInfo(meta: FileMetadata(name: file.name, size: file.size, mimeType: file.mimeType),
|
||||
payloadID: file.payloadID,
|
||||
destinationURL: dest)
|
||||
transferredFiles[file.payloadID]=info
|
||||
}
|
||||
let metadata=TransferMetadata(files: transferredFiles.map({$0.value.meta}), id: id, pinCode: pinCode)
|
||||
DispatchQueue.main.async {
|
||||
self.delegate?.obtainUserConsent(for: metadata, from: self.remoteDeviceInfo!, connection: self)
|
||||
}
|
||||
}
|
||||
|
||||
func submitUserConsent(accepted:Bool){
|
||||
DispatchQueue.global(qos: .utility).async {
|
||||
if accepted{
|
||||
self.acceptTransfer()
|
||||
}else{
|
||||
self.rejectTransfer()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private func acceptTransfer(){
|
||||
do{
|
||||
for (id, file) in transferredFiles{
|
||||
FileManager.default.createFile(atPath: file.destinationURL.path, contents: nil)
|
||||
let handle=try FileHandle(forWritingTo: file.destinationURL)
|
||||
transferredFiles[id]!.fileHandle=handle
|
||||
let progress=Progress()
|
||||
progress.fileURL=file.destinationURL
|
||||
progress.totalUnitCount=file.meta.size
|
||||
progress.kind = .file
|
||||
progress.isPausable=false
|
||||
progress.publish()
|
||||
transferredFiles[id]!.progress=progress
|
||||
transferredFiles[id]!.created=true
|
||||
}
|
||||
|
||||
var frame=Sharing_Nearby_Frame()
|
||||
frame.version = .v1
|
||||
frame.v1.type = .response
|
||||
frame.v1.connectionResponse.status = .accept
|
||||
currentState = .receivingFiles
|
||||
try sendTransferSetupFrame(frame)
|
||||
}catch{
|
||||
print("Error \(error)")
|
||||
protocolError()
|
||||
}
|
||||
}
|
||||
|
||||
private func rejectTransfer(){
|
||||
var frame=Sharing_Nearby_Frame()
|
||||
frame.version = .v1
|
||||
frame.v1.type = .response
|
||||
frame.v1.connectionResponse.status = .reject
|
||||
do{
|
||||
try sendTransferSetupFrame(frame)
|
||||
try sendDisconnectionAndDisconnect()
|
||||
}catch{
|
||||
print("Error \(error)")
|
||||
protocolError()
|
||||
}
|
||||
}
|
||||
|
||||
private func deletePartiallyReceivedFiles() throws{
|
||||
for (_, file) in transferredFiles{
|
||||
guard file.created else { continue }
|
||||
try FileManager.default.removeItem(at: file.destinationURL)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
protocol InboundNearbyConnectionDelegate{
|
||||
func obtainUserConsent(for transfer:TransferMetadata, from device:RemoteDeviceInfo, connection:InboundNearbyConnection)
|
||||
func connectionWasTerminated(connection:InboundNearbyConnection, error:Error?)
|
||||
}
|
||||
426
NearbyShare/NearbyConnection.swift
Normal file
426
NearbyShare/NearbyConnection.swift
Normal file
@@ -0,0 +1,426 @@
|
||||
//
|
||||
// NearbyConnection.swift
|
||||
// NearDrop
|
||||
//
|
||||
// Created by Grishka on 09.04.2023.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Network
|
||||
import CommonCrypto
|
||||
import CryptoKit
|
||||
import System
|
||||
|
||||
import SwiftECC
|
||||
import BigInt
|
||||
|
||||
class NearbyConnection{
|
||||
internal static let SANE_FRAME_LENGTH=5*1024*1024
|
||||
private static let dispatchQueue=DispatchQueue(label: "me.grishka.NearDrop.queue", qos: .utility) // FIFO (non-concurrent) queue to avoid those exciting concurrency bugs
|
||||
|
||||
internal let connection:NWConnection
|
||||
internal var remoteDeviceInfo:RemoteDeviceInfo?
|
||||
private var payloadBuffers:[Int64:NSMutableData]=[:]
|
||||
internal var encryptionDone:Bool=false
|
||||
internal var transferredFiles:[Int64:InternalFileInfo]=[:]
|
||||
public let id:String
|
||||
internal var lastError:Error?
|
||||
private var connectionClosed:Bool=false
|
||||
|
||||
// UKEY2-related state
|
||||
internal var publicKey:ECPublicKey?
|
||||
internal var privateKey:ECPrivateKey?
|
||||
internal var ukeyClientInitMsgData:Data?
|
||||
internal var ukeyServerInitMsgData:Data?
|
||||
|
||||
// SecureMessage encryption keys
|
||||
internal var decryptKey:[UInt8]?
|
||||
internal var encryptKey:[UInt8]?
|
||||
internal var recvHmacKey:SymmetricKey?
|
||||
internal var sendHmacKey:SymmetricKey?
|
||||
|
||||
// SecureMessage sequence numbers
|
||||
private var serverSeq:Int32=0
|
||||
private var clientSeq:Int32=0
|
||||
|
||||
private(set) var pinCode:String?
|
||||
|
||||
init(connection:NWConnection, id:String) {
|
||||
self.connection=connection
|
||||
self.id=id
|
||||
}
|
||||
|
||||
func start(){
|
||||
connection.stateUpdateHandler={state in
|
||||
if case .ready = state {
|
||||
self.connectionReady()
|
||||
self.receiveFrameAsync()
|
||||
} else if case .failed(let err) = state {
|
||||
self.lastError=err
|
||||
print("Error opening socket: \(err)")
|
||||
self.handleConnectionClosure()
|
||||
}
|
||||
}
|
||||
//connection.start(queue: .global(qos: .utility))
|
||||
connection.start(queue: NearbyConnection.dispatchQueue)
|
||||
}
|
||||
|
||||
func connectionReady(){}
|
||||
|
||||
internal func handleConnectionClosure(){
|
||||
print("Connection closed")
|
||||
}
|
||||
|
||||
internal func protocolError(){
|
||||
disconnect()
|
||||
}
|
||||
|
||||
internal func processReceivedFrame(frameData:Data){
|
||||
fatalError()
|
||||
}
|
||||
|
||||
internal func processTransferSetupFrame(_ frame:Sharing_Nearby_Frame) throws{
|
||||
fatalError()
|
||||
}
|
||||
|
||||
internal func isServer() -> Bool{
|
||||
fatalError()
|
||||
}
|
||||
|
||||
internal func processFileChunk(frame:Location_Nearby_Connections_PayloadTransferFrame) throws{
|
||||
protocolError()
|
||||
}
|
||||
|
||||
private func receiveFrameAsync(){
|
||||
connection.receive(minimumIncompleteLength: 4, maximumLength: 4) { content, contentContext, isComplete, error in
|
||||
if self.connectionClosed{
|
||||
return
|
||||
}
|
||||
if isComplete{
|
||||
self.handleConnectionClosure()
|
||||
return
|
||||
}
|
||||
if !(error==nil){
|
||||
self.lastError=error
|
||||
self.protocolError()
|
||||
return
|
||||
}
|
||||
guard let content=content else {
|
||||
assertionFailure()
|
||||
return
|
||||
}
|
||||
let frameLength:UInt32=UInt32(content[0]) << 24 | UInt32(content[1]) << 16 | UInt32(content[2]) << 8 | UInt32(content[3])
|
||||
guard frameLength<NearbyConnection.SANE_FRAME_LENGTH else {
|
||||
self.lastError=NearbyError.protocolError("Unexpected packet length")
|
||||
self.protocolError()
|
||||
return
|
||||
}
|
||||
self.receiveFrameAsync(length: frameLength)
|
||||
}
|
||||
}
|
||||
|
||||
private func receiveFrameAsync(length:UInt32){
|
||||
connection.receive(minimumIncompleteLength: Int(length), maximumLength: Int(length)) { content, contentContext, isComplete, error in
|
||||
if self.connectionClosed{
|
||||
return
|
||||
}
|
||||
if isComplete{
|
||||
self.handleConnectionClosure()
|
||||
return
|
||||
}
|
||||
guard let content=content else {
|
||||
self.protocolError()
|
||||
return
|
||||
}
|
||||
self.processReceivedFrame(frameData: content)
|
||||
self.receiveFrameAsync()
|
||||
}
|
||||
}
|
||||
|
||||
internal func sendFrameAsync(_ frame:Data, completion:(()->Void)?=nil){
|
||||
if connectionClosed{
|
||||
return
|
||||
}
|
||||
var lengthPrefixedData=Data(capacity: frame.count+4)
|
||||
let length:Int=frame.count
|
||||
lengthPrefixedData.append(contentsOf: [
|
||||
UInt8(truncatingIfNeeded: length >> 24),
|
||||
UInt8(truncatingIfNeeded: length >> 16),
|
||||
UInt8(truncatingIfNeeded: length >> 8),
|
||||
UInt8(truncatingIfNeeded: length)
|
||||
])
|
||||
lengthPrefixedData.append(frame)
|
||||
connection.send(content: lengthPrefixedData, completion: .contentProcessed({ error in
|
||||
if let completion=completion{
|
||||
completion()
|
||||
}
|
||||
}))
|
||||
}
|
||||
|
||||
internal func encryptAndSendOfflineFrame(_ frame:Location_Nearby_Connections_OfflineFrame, completion:(()->Void)?=nil) throws{
|
||||
var d2dMsg=Securegcm_DeviceToDeviceMessage()
|
||||
serverSeq+=1
|
||||
d2dMsg.sequenceNumber=serverSeq
|
||||
d2dMsg.message=try frame.serializedData()
|
||||
|
||||
let serializedMsg=[UInt8](try d2dMsg.serializedData())
|
||||
let iv=Data.randomData(length: 16)
|
||||
var encryptedData=Data(count: serializedMsg.count+16)
|
||||
var encryptedLength:size_t=0
|
||||
encryptedData.withUnsafeMutableBytes({
|
||||
let status=CCCrypt(
|
||||
CCOperation(kCCEncrypt),
|
||||
CCAlgorithm(kCCAlgorithmAES128),
|
||||
CCOptions(kCCOptionPKCS7Padding),
|
||||
encryptKey, kCCKeySizeAES256,
|
||||
[UInt8](iv),
|
||||
serializedMsg, serializedMsg.count,
|
||||
$0.baseAddress, $0.count,
|
||||
&encryptedLength
|
||||
)
|
||||
guard status==kCCSuccess else { fatalError("CCCrypt error: \(status)") }
|
||||
})
|
||||
|
||||
var hb=Securemessage_HeaderAndBody()
|
||||
hb.body=encryptedData.prefix(encryptedLength)
|
||||
hb.header=Securemessage_Header()
|
||||
hb.header.encryptionScheme = .aes256Cbc
|
||||
hb.header.signatureScheme = .hmacSha256
|
||||
hb.header.iv=iv
|
||||
var md=Securegcm_GcmMetadata()
|
||||
md.type = .deviceToDeviceMessage
|
||||
md.version=1
|
||||
hb.header.publicMetadata=try md.serializedData()
|
||||
|
||||
var smsg=Securemessage_SecureMessage()
|
||||
smsg.headerAndBody=try hb.serializedData()
|
||||
smsg.signature=Data(HMAC<SHA256>.authenticationCode(for: smsg.headerAndBody, using: sendHmacKey!))
|
||||
sendFrameAsync(try smsg.serializedData(), completion: completion)
|
||||
}
|
||||
|
||||
internal func sendTransferSetupFrame(_ frame:Sharing_Nearby_Frame) throws{
|
||||
var transfer=Location_Nearby_Connections_PayloadTransferFrame()
|
||||
transfer.packetType = .data
|
||||
transfer.payloadChunk.offset=0
|
||||
transfer.payloadChunk.flags=0
|
||||
transfer.payloadChunk.body=try frame.serializedData()
|
||||
transfer.payloadHeader.id=Int64.random(in: Int64.min...Int64.max)
|
||||
transfer.payloadHeader.type = .bytes
|
||||
transfer.payloadHeader.totalSize=Int64(transfer.payloadChunk.body.count)
|
||||
transfer.payloadHeader.isSensitive=false
|
||||
|
||||
var wrapper=Location_Nearby_Connections_OfflineFrame()
|
||||
wrapper.version = .v1
|
||||
wrapper.v1=Location_Nearby_Connections_V1Frame()
|
||||
wrapper.v1.type = .payloadTransfer
|
||||
wrapper.v1.payloadTransfer=transfer
|
||||
try encryptAndSendOfflineFrame(wrapper)
|
||||
|
||||
transfer.payloadChunk.flags=1 // .lastChunk
|
||||
transfer.payloadChunk.offset=Int64(transfer.payloadChunk.body.count)
|
||||
transfer.payloadChunk.clearBody()
|
||||
wrapper.v1.payloadTransfer=transfer
|
||||
try encryptAndSendOfflineFrame(wrapper)
|
||||
}
|
||||
|
||||
internal func decryptAndProcessReceivedSecureMessage(_ smsg:Securemessage_SecureMessage) throws{
|
||||
guard smsg.hasSignature, smsg.hasHeaderAndBody else { throw NearbyError.requiredFieldMissing }
|
||||
let hmac=Data(HMAC<SHA256>.authenticationCode(for: smsg.headerAndBody, using: recvHmacKey!))
|
||||
guard hmac==smsg.signature else { throw NearbyError.protocolError("hmac!=signature") }
|
||||
let headerAndBody=try Securemessage_HeaderAndBody(serializedData: smsg.headerAndBody)
|
||||
var decryptedData=Data(count: headerAndBody.body.count)
|
||||
|
||||
var decryptedLength:Int=0
|
||||
decryptedData.withUnsafeMutableBytes({
|
||||
let status=CCCrypt(
|
||||
CCOperation(kCCDecrypt),
|
||||
CCAlgorithm(kCCAlgorithmAES128),
|
||||
CCOptions(kCCOptionPKCS7Padding),
|
||||
decryptKey, kCCKeySizeAES256,
|
||||
[UInt8](headerAndBody.header.iv),
|
||||
[UInt8](headerAndBody.body), headerAndBody.body.count,
|
||||
$0.baseAddress, $0.count,
|
||||
&decryptedLength
|
||||
)
|
||||
guard status==kCCSuccess else { fatalError("CCCrypt error: \(status)") }
|
||||
})
|
||||
decryptedData=decryptedData.prefix(decryptedLength)
|
||||
let d2dMsg=try Securegcm_DeviceToDeviceMessage(serializedData: decryptedData)
|
||||
guard d2dMsg.hasMessage, d2dMsg.hasSequenceNumber else { throw NearbyError.requiredFieldMissing }
|
||||
clientSeq+=1
|
||||
guard d2dMsg.sequenceNumber==clientSeq else { throw NearbyError.protocolError("Wrong sequence number. Expected \(clientSeq), got \(d2dMsg.sequenceNumber)") }
|
||||
let offlineFrame=try Location_Nearby_Connections_OfflineFrame(serializedData: d2dMsg.message)
|
||||
guard offlineFrame.hasV1, offlineFrame.v1.hasType else { throw NearbyError.requiredFieldMissing }
|
||||
|
||||
if case .payloadTransfer = offlineFrame.v1.type {
|
||||
guard offlineFrame.v1.hasPayloadTransfer else { throw NearbyError.requiredFieldMissing }
|
||||
let payloadTransfer=offlineFrame.v1.payloadTransfer
|
||||
let header=payloadTransfer.payloadHeader;
|
||||
let chunk=payloadTransfer.payloadChunk;
|
||||
guard header.hasType, header.hasID else { throw NearbyError.requiredFieldMissing }
|
||||
guard payloadTransfer.hasPayloadChunk, chunk.hasOffset, chunk.hasFlags else { throw NearbyError.requiredFieldMissing }
|
||||
if case .bytes = header.type{
|
||||
let payloadID=header.id
|
||||
if header.totalSize>InboundNearbyConnection.SANE_FRAME_LENGTH{
|
||||
payloadBuffers.removeValue(forKey: payloadID)
|
||||
throw NearbyError.protocolError("Payload too large (\(header.totalSize) bytes)")
|
||||
}
|
||||
if payloadBuffers[payloadID]==nil {
|
||||
payloadBuffers[payloadID]=NSMutableData(capacity: Int(header.totalSize))
|
||||
}
|
||||
let buffer=payloadBuffers[payloadID]!
|
||||
guard chunk.offset==buffer.count else {
|
||||
payloadBuffers.removeValue(forKey: payloadID)
|
||||
throw NearbyError.protocolError("Unexpected chunk offset \(chunk.offset), expected \(buffer.count)")
|
||||
}
|
||||
if chunk.hasBody {
|
||||
buffer.append(chunk.body)
|
||||
}
|
||||
if (chunk.flags & 1)==1 {
|
||||
payloadBuffers.removeValue(forKey: payloadID)
|
||||
let innerFrame=try Sharing_Nearby_Frame(serializedData: buffer as Data)
|
||||
try processTransferSetupFrame(innerFrame)
|
||||
}
|
||||
}else if case .file = header.type{
|
||||
try processFileChunk(frame: payloadTransfer)
|
||||
}
|
||||
}else if case .keepAlive = offlineFrame.v1.type{
|
||||
#if DEBUG
|
||||
print("Sent keep-alive")
|
||||
#endif
|
||||
sendKeepAlive(ack: true)
|
||||
}else{
|
||||
print("Unhandled offline frame encrypted: \(offlineFrame)")
|
||||
}
|
||||
}
|
||||
|
||||
internal static func pinCodeFromAuthKey(_ key:SymmetricKey) -> String{
|
||||
var hash:Int=0
|
||||
var multiplier:Int=1
|
||||
let keyBytes:[UInt8]=key.withUnsafeBytes({
|
||||
return [UInt8]($0)
|
||||
})
|
||||
|
||||
for _byte in keyBytes {
|
||||
let byte=Int(Int8(bitPattern: _byte))
|
||||
hash=(hash+byte*multiplier)%9973
|
||||
multiplier=(multiplier*31)%9973
|
||||
}
|
||||
|
||||
return String(format: "%04d", abs(hash))
|
||||
}
|
||||
|
||||
internal func finalizeKeyExchange(peerKey:Securemessage_GenericPublicKey) throws{
|
||||
guard peerKey.hasEcP256PublicKey else { throw NearbyError.requiredFieldMissing }
|
||||
|
||||
let domain=Domain.instance(curve: .EC256r1)
|
||||
var clientX=peerKey.ecP256PublicKey.x
|
||||
var clientY=peerKey.ecP256PublicKey.y
|
||||
if clientX.count>32{
|
||||
clientX=clientX.suffix(32)
|
||||
}
|
||||
if clientY.count>32{
|
||||
clientY=clientY.suffix(32)
|
||||
}
|
||||
let key=try ECPublicKey(domain: domain, w: Point(BInt(magnitude: [UInt8](clientX)), BInt(magnitude: [UInt8](clientY))))
|
||||
|
||||
let dhs=(try privateKey?.domain.multiplyPoint(key.w, privateKey!.s).x.asMagnitudeBytes())!
|
||||
var sha=SHA256()
|
||||
sha.update(data: dhs)
|
||||
let derivedSecretKey=Data(sha.finalize())
|
||||
|
||||
var ukeyInfo=Data()
|
||||
ukeyInfo.append(ukeyClientInitMsgData!)
|
||||
ukeyInfo.append(ukeyServerInitMsgData!)
|
||||
let authString=HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 auth".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
|
||||
let nextSecret=HKDF<SHA256>.deriveKey(inputKeyMaterial: SymmetricKey(data: derivedSecretKey), salt: "UKEY2 v1 next".data(using: .utf8)!, info: ukeyInfo, outputByteCount: 32)
|
||||
|
||||
pinCode=NearbyConnection.pinCodeFromAuthKey(authString)
|
||||
|
||||
let salt:Data=Data([0x82, 0xAA, 0x55, 0xA0, 0xD3, 0x97, 0xF8, 0x83, 0x46, 0xCA, 0x1C,
|
||||
0xEE, 0x8D, 0x39, 0x09, 0xB9, 0x5F, 0x13, 0xFA, 0x7D, 0xEB, 0x1D,
|
||||
0x4A, 0xB3, 0x83, 0x76, 0xB8, 0x25, 0x6D, 0xA8, 0x55, 0x10])
|
||||
|
||||
let d2dClientKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: nextSecret, salt: salt, info: "client".data(using: .utf8)!, outputByteCount: 32)
|
||||
let d2dServerKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: nextSecret, salt: salt, info: "server".data(using: .utf8)!, outputByteCount: 32)
|
||||
|
||||
sha=SHA256()
|
||||
sha.update(data: "SecureMessage".data(using: .utf8)!)
|
||||
let smsgSalt=Data(sha.finalize())
|
||||
|
||||
let clientKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
|
||||
let clientHmacKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dClientKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
|
||||
let serverKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "ENC:2".data(using: .utf8)!, outputByteCount: 32).withUnsafeBytes({return [UInt8]($0)})
|
||||
let serverHmacKey=HKDF<SHA256>.deriveKey(inputKeyMaterial: d2dServerKey, salt: smsgSalt, info: "SIG:1".data(using: .utf8)!, outputByteCount: 32)
|
||||
|
||||
if isServer(){
|
||||
decryptKey=clientKey
|
||||
recvHmacKey=clientHmacKey
|
||||
encryptKey=serverKey
|
||||
sendHmacKey=serverHmacKey
|
||||
}else{
|
||||
decryptKey=serverKey
|
||||
recvHmacKey=serverHmacKey
|
||||
encryptKey=clientKey
|
||||
sendHmacKey=clientHmacKey
|
||||
}
|
||||
}
|
||||
|
||||
internal func disconnect(){
|
||||
connection.send(content: nil, isComplete: true, completion: .contentProcessed({ error in
|
||||
self.handleConnectionClosure()
|
||||
}))
|
||||
connectionClosed=true
|
||||
}
|
||||
|
||||
internal func sendDisconnectionAndDisconnect() throws{
|
||||
var offlineFrame=Location_Nearby_Connections_OfflineFrame()
|
||||
offlineFrame.version = .v1
|
||||
offlineFrame.v1.type = .disconnection
|
||||
offlineFrame.v1.disconnection=Location_Nearby_Connections_DisconnectionFrame()
|
||||
|
||||
if encryptionDone{
|
||||
try encryptAndSendOfflineFrame(offlineFrame)
|
||||
}else{
|
||||
sendFrameAsync(try offlineFrame.serializedData())
|
||||
}
|
||||
disconnect()
|
||||
}
|
||||
|
||||
internal func sendUkey2Alert(type:Securegcm_Ukey2Alert.AlertType){
|
||||
var alert=Securegcm_Ukey2Alert()
|
||||
alert.type=type
|
||||
var msg=Securegcm_Ukey2Message()
|
||||
msg.messageType = .alert
|
||||
msg.messageData = try! alert.serializedData()
|
||||
sendFrameAsync(try! msg.serializedData())
|
||||
disconnect()
|
||||
}
|
||||
|
||||
internal func sendKeepAlive(ack:Bool){
|
||||
var offlineFrame=Location_Nearby_Connections_OfflineFrame()
|
||||
offlineFrame.version = .v1
|
||||
offlineFrame.v1.type = .keepAlive
|
||||
offlineFrame.v1.keepAlive.ack=ack
|
||||
|
||||
do{
|
||||
if encryptionDone{
|
||||
try encryptAndSendOfflineFrame(offlineFrame)
|
||||
}else{
|
||||
sendFrameAsync(try offlineFrame.serializedData())
|
||||
}
|
||||
}catch{
|
||||
print("Error sending KEEP_ALIVE: \(error)")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
struct InternalFileInfo{
|
||||
let meta:FileMetadata
|
||||
let payloadID:Int64
|
||||
let destinationURL:URL
|
||||
var bytesTransferred:Int64=0
|
||||
var fileHandle:FileHandle?
|
||||
var progress:Progress?
|
||||
var created:Bool=false
|
||||
}
|
||||
374
NearbyShare/NearbyConnectionManager.swift
Normal file
374
NearbyShare/NearbyConnectionManager.swift
Normal file
@@ -0,0 +1,374 @@
|
||||
//
|
||||
// NearbyConnectionManager.swift
|
||||
// NearDrop
|
||||
//
|
||||
// Created by Grishka on 08.04.2023.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Network
|
||||
import System
|
||||
|
||||
public struct RemoteDeviceInfo{
|
||||
public let name:String
|
||||
public let type:DeviceType
|
||||
public var id:String?
|
||||
|
||||
init(name: String, type: DeviceType, id: String? = nil) {
|
||||
self.name = name
|
||||
self.type = type
|
||||
self.id = id
|
||||
}
|
||||
|
||||
init(info:EndpointInfo){
|
||||
self.name=info.name
|
||||
self.type=info.deviceType
|
||||
}
|
||||
|
||||
public enum DeviceType:Int32{
|
||||
case unknown=0
|
||||
case phone
|
||||
case tablet
|
||||
case computer
|
||||
|
||||
public static func fromRawValue(value:Int) -> DeviceType{
|
||||
switch value {
|
||||
case 0:
|
||||
return .unknown
|
||||
case 1:
|
||||
return .phone
|
||||
case 2:
|
||||
return .tablet
|
||||
case 3:
|
||||
return .computer
|
||||
default:
|
||||
return .unknown
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public enum NearbyError:Error{
|
||||
case protocolError(_ message:String)
|
||||
case requiredFieldMissing
|
||||
case ukey2
|
||||
case inputOutput(cause:Errno)
|
||||
case canceled(reason:CancellationReason)
|
||||
|
||||
public enum CancellationReason{
|
||||
case userRejected, userCanceled, notEnoughSpace, unsupportedType, timedOut
|
||||
}
|
||||
}
|
||||
|
||||
public struct TransferMetadata{
|
||||
public let files:[FileMetadata]
|
||||
public let id:String
|
||||
public let pinCode:String?
|
||||
}
|
||||
|
||||
public struct FileMetadata{
|
||||
public let name:String
|
||||
public let size:Int64
|
||||
public let mimeType:String
|
||||
}
|
||||
|
||||
struct FoundServiceInfo{
|
||||
let service:NWBrowser.Result
|
||||
var device:RemoteDeviceInfo?
|
||||
}
|
||||
|
||||
struct OutgoingTransferInfo{
|
||||
let service:NWBrowser.Result
|
||||
let device:RemoteDeviceInfo
|
||||
let connection:OutboundNearbyConnection
|
||||
let delegate:ShareExtensionDelegate
|
||||
}
|
||||
|
||||
struct EndpointInfo{
|
||||
let name:String
|
||||
let deviceType:RemoteDeviceInfo.DeviceType
|
||||
|
||||
init(name: String, deviceType: RemoteDeviceInfo.DeviceType){
|
||||
self.name = name
|
||||
self.deviceType = deviceType
|
||||
}
|
||||
|
||||
init?(data:Data){
|
||||
guard data.count>17 else {return nil}
|
||||
let deviceNameLength=Int(data[17])
|
||||
guard data.count>=deviceNameLength+18 else {return nil}
|
||||
guard let deviceName=String(data: data[18..<(18+deviceNameLength)], encoding: .utf8) else {return nil}
|
||||
let rawDeviceType:Int=Int(data[0] & 7) >> 1
|
||||
self.name=deviceName
|
||||
self.deviceType=RemoteDeviceInfo.DeviceType.fromRawValue(value: rawDeviceType)
|
||||
}
|
||||
|
||||
func serialize()->Data{
|
||||
// 1 byte: Version(3 bits)|Visibility(1 bit)|Device Type(3 bits)|Reserved(1 bits)
|
||||
// Device types: unknown=0, phone=1, tablet=2, laptop=3
|
||||
var endpointInfo:[UInt8]=[UInt8(deviceType.rawValue << 1)]
|
||||
// 16 bytes: unknown random bytes
|
||||
for _ in 0...15{
|
||||
endpointInfo.append(UInt8.random(in: 0...255))
|
||||
}
|
||||
// Device name in UTF-8 prefixed with 1-byte length
|
||||
var nameChars=[UInt8](name.utf8)
|
||||
if nameChars.count>255{
|
||||
nameChars=[UInt8](nameChars[0..<255])
|
||||
}
|
||||
endpointInfo.append(UInt8(nameChars.count))
|
||||
for ch in nameChars{
|
||||
endpointInfo.append(UInt8(ch))
|
||||
}
|
||||
return Data(endpointInfo)
|
||||
}
|
||||
}
|
||||
|
||||
public protocol MainAppDelegate{
|
||||
func obtainUserConsent(for transfer:TransferMetadata, from device:RemoteDeviceInfo)
|
||||
func incomingTransfer(id:String, didFinishWith error:Error?)
|
||||
}
|
||||
|
||||
public protocol ShareExtensionDelegate:AnyObject{
|
||||
func addDevice(device:RemoteDeviceInfo)
|
||||
func removeDevice(id:String)
|
||||
func connectionWasEstablished(pinCode:String)
|
||||
func connectionFailed(with error:Error)
|
||||
func transferAccepted()
|
||||
func transferProgress(progress:Double)
|
||||
func transferFinished()
|
||||
}
|
||||
|
||||
public class NearbyConnectionManager : NSObject, NetServiceDelegate, InboundNearbyConnectionDelegate, OutboundNearbyConnectionDelegate{
|
||||
|
||||
private var tcpListener:NWListener;
|
||||
public let endpointID:[UInt8]=generateEndpointID()
|
||||
private var mdnsService:NetService?
|
||||
private var activeConnections:[String:InboundNearbyConnection]=[:]
|
||||
private var foundServices:[String:FoundServiceInfo]=[:]
|
||||
private var shareExtensionDelegates:[ShareExtensionDelegate]=[]
|
||||
private var outgoingTransfers:[String:OutgoingTransferInfo]=[:]
|
||||
public var mainAppDelegate:(any MainAppDelegate)?
|
||||
private var discoveryRefCount=0
|
||||
|
||||
private var browser:NWBrowser?
|
||||
|
||||
public static let shared=NearbyConnectionManager()
|
||||
|
||||
override init() {
|
||||
tcpListener=try! NWListener(using: NWParameters(tls: .none))
|
||||
super.init()
|
||||
}
|
||||
|
||||
public func becomeVisible(){
|
||||
startTCPListener()
|
||||
}
|
||||
|
||||
private func startTCPListener(){
|
||||
tcpListener.stateUpdateHandler={(state:NWListener.State) in
|
||||
if case .ready = state {
|
||||
self.initMDNS()
|
||||
}
|
||||
}
|
||||
tcpListener.newConnectionHandler={(connection:NWConnection) in
|
||||
let id=UUID().uuidString
|
||||
let conn=InboundNearbyConnection(connection: connection, id: id)
|
||||
self.activeConnections[id]=conn
|
||||
conn.delegate=self
|
||||
conn.start()
|
||||
}
|
||||
tcpListener.start(queue: .global(qos: .utility))
|
||||
}
|
||||
|
||||
private static func generateEndpointID()->[UInt8]{
|
||||
var id:[UInt8]=[]
|
||||
let alphabet="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ".compactMap {UInt8($0.asciiValue!)}
|
||||
for _ in 0...3{
|
||||
id.append(alphabet[Int.random(in: 0..<alphabet.count)])
|
||||
}
|
||||
return id
|
||||
}
|
||||
|
||||
private func initMDNS(){
|
||||
let nameBytes:[UInt8]=[
|
||||
0x23, // PCP
|
||||
endpointID[0], endpointID[1], endpointID[2], endpointID[3],
|
||||
0xFC, 0x9F, 0x5E, // Service ID hash
|
||||
0, 0
|
||||
]
|
||||
let name=Data(nameBytes).urlSafeBase64EncodedString()
|
||||
let endpointInfo=EndpointInfo(name: Host.current().localizedName!, deviceType: .computer)
|
||||
|
||||
let port:Int32=Int32(tcpListener.port!.rawValue)
|
||||
mdnsService=NetService(domain: "", type: "_FC9F5ED42C8A._tcp.", name: name, port: port)
|
||||
mdnsService?.delegate=self
|
||||
mdnsService?.includesPeerToPeer=true
|
||||
mdnsService?.setTXTRecord(NetService.data(fromTXTRecord: [
|
||||
"n": endpointInfo.serialize().urlSafeBase64EncodedString().data(using: .utf8)!
|
||||
]))
|
||||
mdnsService?.publish()
|
||||
}
|
||||
|
||||
func obtainUserConsent(for transfer: TransferMetadata, from device: RemoteDeviceInfo, connection: InboundNearbyConnection) {
|
||||
guard let delegate=mainAppDelegate else {return}
|
||||
delegate.obtainUserConsent(for: transfer, from: device)
|
||||
}
|
||||
|
||||
func connectionWasTerminated(connection:InboundNearbyConnection, error:Error?){
|
||||
guard let delegate=mainAppDelegate else {return}
|
||||
delegate.incomingTransfer(id: connection.id, didFinishWith: error)
|
||||
activeConnections.removeValue(forKey: connection.id)
|
||||
}
|
||||
|
||||
public func submitUserConsent(transferID:String, accept:Bool){
|
||||
guard let conn=activeConnections[transferID] else {return}
|
||||
conn.submitUserConsent(accepted: accept)
|
||||
}
|
||||
|
||||
public func startDeviceDiscovery(){
|
||||
if discoveryRefCount==0{
|
||||
foundServices.removeAll()
|
||||
if browser==nil{
|
||||
browser=NWBrowser(for: .bonjourWithTXTRecord(type: "_FC9F5ED42C8A._tcp.", domain: nil), using: .tcp)
|
||||
browser?.browseResultsChangedHandler={newResults, changes in
|
||||
for change in changes{
|
||||
switch change{
|
||||
case let .added(res):
|
||||
self.maybeAddFoundDevice(service: res)
|
||||
case let .removed(res):
|
||||
self.maybeRemoveFoundDevice(service: res)
|
||||
default:
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
browser?.start(queue: .main)
|
||||
}
|
||||
discoveryRefCount+=1
|
||||
}
|
||||
|
||||
public func stopDeviceDiscovery(){
|
||||
discoveryRefCount-=1
|
||||
assert(discoveryRefCount>=0)
|
||||
if discoveryRefCount==0{
|
||||
browser?.cancel()
|
||||
browser=nil
|
||||
}
|
||||
}
|
||||
|
||||
public func addShareExtensionDelegate(_ delegate:ShareExtensionDelegate){
|
||||
shareExtensionDelegates.append(delegate)
|
||||
for service in foundServices.values{
|
||||
guard let device=service.device else {continue}
|
||||
delegate.addDevice(device: device)
|
||||
}
|
||||
}
|
||||
|
||||
public func removeShareExtensionDelegate(_ delegate:ShareExtensionDelegate){
|
||||
shareExtensionDelegates.removeAll(where: {$0===delegate})
|
||||
}
|
||||
|
||||
public func cancelOutgoingTransfer(id:String){
|
||||
guard let transfer=outgoingTransfers[id] else {return}
|
||||
transfer.connection.cancel()
|
||||
}
|
||||
|
||||
private func endpointID(for service:NWBrowser.Result)->String?{
|
||||
guard case let NWEndpoint.service(name: serviceName, type: _, domain: _, interface: _)=service.endpoint else {return nil}
|
||||
guard let nameData=Data.dataFromUrlSafeBase64(serviceName) else {return nil}
|
||||
guard nameData.count>=10 else {return nil}
|
||||
let pcp=nameData[0]
|
||||
guard pcp==0x23 else {return nil}
|
||||
let endpointID=String(data: nameData.subdata(in: 1..<5), encoding: .ascii)!
|
||||
let serviceIDHash=nameData.subdata(in: 5..<8)
|
||||
guard serviceIDHash==Data([0xFC, 0x9F, 0x5E]) else {return nil}
|
||||
return endpointID
|
||||
}
|
||||
|
||||
private func maybeAddFoundDevice(service:NWBrowser.Result){
|
||||
#if DEBUG
|
||||
print("found service \(service)")
|
||||
#endif
|
||||
guard let endpointID=endpointID(for: service) else {return}
|
||||
#if DEBUG
|
||||
print("service name is valid, endpoint ID \(endpointID)")
|
||||
#endif
|
||||
var foundService=FoundServiceInfo(service: service)
|
||||
|
||||
guard case let NWBrowser.Result.Metadata.bonjour(txtRecord)=service.metadata else {return}
|
||||
guard let endpointInfoEncoded=txtRecord.dictionary["n"] else {return}
|
||||
guard let endpointInfo=Data.dataFromUrlSafeBase64(endpointInfoEncoded) else {return}
|
||||
guard endpointInfo.count>=19 else {return}
|
||||
let deviceType=RemoteDeviceInfo.DeviceType.fromRawValue(value: (Int(endpointInfo[0]) >> 1) & 7)
|
||||
let deviceNameLength=Int(endpointInfo[17])
|
||||
guard endpointInfo.count>=deviceNameLength+17 else {return}
|
||||
guard let deviceName=String(data: endpointInfo.subdata(in: 18..<(18+deviceNameLength)), encoding: .utf8) else {return}
|
||||
|
||||
let deviceInfo=RemoteDeviceInfo(name: deviceName, type: deviceType, id: endpointID)
|
||||
foundService.device=deviceInfo
|
||||
foundServices[endpointID]=foundService
|
||||
for delegate in shareExtensionDelegates{
|
||||
delegate.addDevice(device: deviceInfo)
|
||||
}
|
||||
}
|
||||
|
||||
private func maybeRemoveFoundDevice(service:NWBrowser.Result){
|
||||
guard let endpointID=endpointID(for: service) else {return}
|
||||
guard let _=foundServices.removeValue(forKey: endpointID) else {return}
|
||||
for delegate in shareExtensionDelegates {
|
||||
delegate.removeDevice(id: endpointID)
|
||||
}
|
||||
}
|
||||
|
||||
public func startOutgoingTransfer(deviceID:String, delegate:ShareExtensionDelegate, urls:[URL]){
|
||||
guard let info=foundServices[deviceID] else {return}
|
||||
let tcp=NWProtocolTCP.Options.init()
|
||||
tcp.noDelay=true
|
||||
let nwconn=NWConnection(to: info.service.endpoint, using: NWParameters(tls: .none, tcp: tcp))
|
||||
let conn=OutboundNearbyConnection(connection: nwconn, id: deviceID, urlsToSend: urls)
|
||||
conn.delegate=self
|
||||
let transfer=OutgoingTransferInfo(service: info.service, device: info.device!, connection: conn, delegate: delegate)
|
||||
outgoingTransfers[deviceID]=transfer
|
||||
conn.start()
|
||||
}
|
||||
|
||||
func outboundConnectionWasEstablished(connection: OutboundNearbyConnection) {
|
||||
guard let transfer=outgoingTransfers[connection.id] else {return}
|
||||
DispatchQueue.main.async {
|
||||
transfer.delegate.connectionWasEstablished(pinCode: connection.pinCode!)
|
||||
}
|
||||
}
|
||||
|
||||
func outboundConnectionTransferAccepted(connection: OutboundNearbyConnection) {
|
||||
guard let transfer=outgoingTransfers[connection.id] else {return}
|
||||
DispatchQueue.main.async {
|
||||
transfer.delegate.transferAccepted()
|
||||
}
|
||||
}
|
||||
|
||||
func outboundConnection(connection: OutboundNearbyConnection, transferProgress: Double) {
|
||||
guard let transfer=outgoingTransfers[connection.id] else {return}
|
||||
DispatchQueue.main.async {
|
||||
transfer.delegate.transferProgress(progress: transferProgress)
|
||||
}
|
||||
}
|
||||
|
||||
func outboundConnection(connection: OutboundNearbyConnection, failedWithError: Error) {
|
||||
guard let transfer=outgoingTransfers[connection.id] else {return}
|
||||
DispatchQueue.main.async {
|
||||
transfer.delegate.connectionFailed(with: failedWithError)
|
||||
}
|
||||
outgoingTransfers.removeValue(forKey: connection.id)
|
||||
}
|
||||
|
||||
func outboundConnectionTransferFinished(connection: OutboundNearbyConnection) {
|
||||
guard let transfer=outgoingTransfers[connection.id] else {return}
|
||||
DispatchQueue.main.async {
|
||||
transfer.delegate.transferFinished()
|
||||
}
|
||||
outgoingTransfers.removeValue(forKey: connection.id)
|
||||
}
|
||||
}
|
||||
|
||||
424
NearbyShare/OutboundNearbyConnection.swift
Normal file
424
NearbyShare/OutboundNearbyConnection.swift
Normal file
@@ -0,0 +1,424 @@
|
||||
//
|
||||
// OutboundNearbyConnection.swift
|
||||
// NearbyShare
|
||||
//
|
||||
// Created by Grishka on 23.09.2023.
|
||||
//
|
||||
|
||||
import Foundation
|
||||
import Network
|
||||
import CryptoKit
|
||||
import CommonCrypto
|
||||
import System
|
||||
import UniformTypeIdentifiers
|
||||
|
||||
import SwiftECC
|
||||
import BigInt
|
||||
|
||||
class OutboundNearbyConnection:NearbyConnection{
|
||||
private var currentState:State = .initial
|
||||
private let urlsToSend:[URL]
|
||||
private var ukeyClientFinishMsgData:Data?
|
||||
private var queue:[OutgoingFileTransfer]=[]
|
||||
private var currentTransfer:OutgoingFileTransfer?
|
||||
public var delegate:OutboundNearbyConnectionDelegate?
|
||||
private var totalBytesToSend:Int64=0
|
||||
private var totalBytesSent:Int64=0
|
||||
private var cancelled:Bool=false
|
||||
|
||||
enum State{
|
||||
case initial, sentUkeyClientInit, sentUkeyClientFinish, sentPairedKeyEncryption, sentPairedKeyResult, sentIntroduction, sendingFiles
|
||||
}
|
||||
|
||||
init(connection: NWConnection, id: String, urlsToSend:[URL]){
|
||||
self.urlsToSend=urlsToSend
|
||||
super.init(connection: connection, id: id)
|
||||
}
|
||||
|
||||
deinit {
|
||||
if let transfer=currentTransfer, let handle=transfer.handle{
|
||||
try? handle.close()
|
||||
}
|
||||
for transfer in queue{
|
||||
if let handle=transfer.handle{
|
||||
try? handle.close()
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public func cancel(){
|
||||
cancelled=true
|
||||
if encryptionDone{
|
||||
var cancel=Sharing_Nearby_Frame()
|
||||
cancel.version = .v1
|
||||
cancel.v1=Sharing_Nearby_V1Frame()
|
||||
cancel.v1.type = .cancel
|
||||
try? sendTransferSetupFrame(cancel)
|
||||
}
|
||||
try? sendDisconnectionAndDisconnect()
|
||||
}
|
||||
|
||||
override func connectionReady() {
|
||||
super.connectionReady()
|
||||
do{
|
||||
try sendConnectionRequest()
|
||||
try sendUkey2ClientInit()
|
||||
}catch{
|
||||
lastError=error
|
||||
protocolError()
|
||||
}
|
||||
}
|
||||
|
||||
override func isServer() -> Bool {
|
||||
return false
|
||||
}
|
||||
|
||||
override func processReceivedFrame(frameData: Data) {
|
||||
do{
|
||||
#if DEBUG
|
||||
print("received \(frameData), state is \(currentState)")
|
||||
#endif
|
||||
switch currentState {
|
||||
case .initial:
|
||||
protocolError()
|
||||
case .sentUkeyClientInit:
|
||||
try processUkey2ServerInit(frame: try Securegcm_Ukey2Message(serializedData: frameData), raw: frameData)
|
||||
case .sentUkeyClientFinish:
|
||||
try processConnectionResponse(frame: try Location_Nearby_Connections_OfflineFrame(serializedData: frameData))
|
||||
default:
|
||||
let smsg=try Securemessage_SecureMessage(serializedData: frameData)
|
||||
try decryptAndProcessReceivedSecureMessage(smsg)
|
||||
}
|
||||
}catch{
|
||||
if case NearbyError.ukey2=error{
|
||||
}else if currentState == .sentUkeyClientInit{
|
||||
sendUkey2Alert(type: .badMessage)
|
||||
}
|
||||
lastError=error
|
||||
protocolError()
|
||||
}
|
||||
}
|
||||
|
||||
override func processTransferSetupFrame(_ frame: Sharing_Nearby_Frame) throws {
|
||||
if frame.hasV1 && frame.v1.hasType, case .cancel = frame.v1.type {
|
||||
print("Transfer canceled")
|
||||
try sendDisconnectionAndDisconnect()
|
||||
delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .userCanceled))
|
||||
return
|
||||
}
|
||||
print(frame)
|
||||
switch currentState{
|
||||
case .sentPairedKeyEncryption:
|
||||
try processPairedKeyEncryption(frame: frame)
|
||||
case .sentPairedKeyResult:
|
||||
try processPairedKeyResult(frame: frame)
|
||||
case .sentIntroduction:
|
||||
try processConsent(frame: frame)
|
||||
case .sendingFiles:
|
||||
break
|
||||
default:
|
||||
assertionFailure("Unexpected state \(currentState)")
|
||||
}
|
||||
}
|
||||
|
||||
override func protocolError() {
|
||||
super.protocolError()
|
||||
delegate?.outboundConnection(connection: self, failedWithError: lastError!)
|
||||
}
|
||||
|
||||
private func sendConnectionRequest() throws {
|
||||
var frame=Location_Nearby_Connections_OfflineFrame()
|
||||
frame.version = .v1
|
||||
frame.v1=Location_Nearby_Connections_V1Frame()
|
||||
frame.v1.type = .connectionRequest
|
||||
frame.v1.connectionRequest=Location_Nearby_Connections_ConnectionRequestFrame()
|
||||
frame.v1.connectionRequest.endpointID=String(bytes: NearbyConnectionManager.shared.endpointID, encoding: .ascii)!
|
||||
frame.v1.connectionRequest.endpointName=Host.current().localizedName!
|
||||
let endpointInfo=EndpointInfo(name: Host.current().localizedName!, deviceType: .computer)
|
||||
frame.v1.connectionRequest.endpointInfo=endpointInfo.serialize()
|
||||
frame.v1.connectionRequest.mediums=[.wifiLan]
|
||||
sendFrameAsync(try frame.serializedData())
|
||||
}
|
||||
|
||||
private func sendUkey2ClientInit() throws {
|
||||
let domain=Domain.instance(curve: .EC256r1)
|
||||
let (pubKey, privKey)=domain.makeKeyPair()
|
||||
publicKey=pubKey
|
||||
privateKey=privKey
|
||||
|
||||
var finishFrame=Securegcm_Ukey2Message()
|
||||
finishFrame.messageType = .clientFinish
|
||||
var finish=Securegcm_Ukey2ClientFinished()
|
||||
var pkey=Securemessage_GenericPublicKey()
|
||||
pkey.type = .ecP256
|
||||
pkey.ecP256PublicKey=Securemessage_EcP256PublicKey()
|
||||
pkey.ecP256PublicKey.x=Data(pubKey.w.x.asSignedBytes())
|
||||
pkey.ecP256PublicKey.y=Data(pubKey.w.y.asSignedBytes())
|
||||
finish.publicKey=try pkey.serializedData()
|
||||
finishFrame.messageData=try finish.serializedData()
|
||||
ukeyClientFinishMsgData=try finishFrame.serializedData()
|
||||
|
||||
var frame=Securegcm_Ukey2Message()
|
||||
frame.messageType = .clientInit
|
||||
|
||||
var clientInit=Securegcm_Ukey2ClientInit()
|
||||
clientInit.version=1
|
||||
clientInit.random=Data.randomData(length: 32)
|
||||
clientInit.nextProtocol="AES_256_CBC-HMAC_SHA256"
|
||||
var sha=SHA512()
|
||||
sha.update(data: ukeyClientFinishMsgData!)
|
||||
var commitment=Securegcm_Ukey2ClientInit.CipherCommitment()
|
||||
commitment.commitment=Data(sha.finalize())
|
||||
commitment.handshakeCipher = .p256Sha512
|
||||
clientInit.cipherCommitments.append(commitment)
|
||||
frame.messageData=try clientInit.serializedData()
|
||||
|
||||
ukeyClientInitMsgData=try frame.serializedData()
|
||||
sendFrameAsync(ukeyClientInitMsgData!)
|
||||
currentState = .sentUkeyClientInit
|
||||
}
|
||||
|
||||
private func processUkey2ServerInit(frame:Securegcm_Ukey2Message, raw:Data) throws{
|
||||
ukeyServerInitMsgData=raw
|
||||
guard frame.messageType == .serverInit else{
|
||||
sendUkey2Alert(type: .badMessageType)
|
||||
throw NearbyError.ukey2
|
||||
}
|
||||
let serverInit=try Securegcm_Ukey2ServerInit(serializedData: frame.messageData)
|
||||
guard serverInit.version==1 else{
|
||||
sendUkey2Alert(type: .badVersion)
|
||||
throw NearbyError.ukey2
|
||||
}
|
||||
guard serverInit.random.count==32 else{
|
||||
sendUkey2Alert(type: .badRandom)
|
||||
throw NearbyError.ukey2
|
||||
}
|
||||
guard serverInit.handshakeCipher == .p256Sha512 else{
|
||||
sendUkey2Alert(type: .badHandshakeCipher)
|
||||
throw NearbyError.ukey2
|
||||
}
|
||||
|
||||
let serverKey=try Securemessage_GenericPublicKey(serializedData: serverInit.publicKey)
|
||||
try finalizeKeyExchange(peerKey: serverKey)
|
||||
sendFrameAsync(ukeyClientFinishMsgData!)
|
||||
currentState = .sentUkeyClientFinish
|
||||
|
||||
var resp=Location_Nearby_Connections_OfflineFrame()
|
||||
resp.version = .v1
|
||||
resp.v1=Location_Nearby_Connections_V1Frame()
|
||||
resp.v1.type = .connectionResponse
|
||||
resp.v1.connectionResponse=Location_Nearby_Connections_ConnectionResponseFrame()
|
||||
resp.v1.connectionResponse.response = .accept
|
||||
resp.v1.connectionResponse.status=0
|
||||
resp.v1.connectionResponse.osInfo=Location_Nearby_Connections_OsInfo()
|
||||
resp.v1.connectionResponse.osInfo.type = .apple
|
||||
sendFrameAsync(try resp.serializedData())
|
||||
|
||||
encryptionDone=true
|
||||
delegate?.outboundConnectionWasEstablished(connection: self)
|
||||
}
|
||||
|
||||
private func processConnectionResponse(frame:Location_Nearby_Connections_OfflineFrame) throws{
|
||||
#if DEBUG
|
||||
print("connection response: \(frame)")
|
||||
#endif
|
||||
guard frame.version == .v1 else {throw NearbyError.protocolError("Unexpected offline frame version \(frame.version)")}
|
||||
guard frame.v1.type == .connectionResponse else {throw NearbyError.protocolError("Unexpected frame type \(frame.v1.type)")}
|
||||
guard frame.v1.connectionResponse.response == .accept else {throw NearbyError.protocolError("Connection was rejected by recipient")}
|
||||
|
||||
var pairedEncryption=Sharing_Nearby_Frame()
|
||||
pairedEncryption.version = .v1
|
||||
pairedEncryption.v1=Sharing_Nearby_V1Frame()
|
||||
pairedEncryption.v1.type = .pairedKeyEncryption
|
||||
pairedEncryption.v1.pairedKeyEncryption=Sharing_Nearby_PairedKeyEncryptionFrame()
|
||||
pairedEncryption.v1.pairedKeyEncryption.secretIDHash=Data.randomData(length: 6)
|
||||
pairedEncryption.v1.pairedKeyEncryption.signedData=Data.randomData(length: 72)
|
||||
try sendTransferSetupFrame(pairedEncryption)
|
||||
|
||||
currentState = .sentPairedKeyEncryption
|
||||
}
|
||||
|
||||
private func processPairedKeyEncryption(frame:Sharing_Nearby_Frame) throws{
|
||||
guard frame.hasV1, frame.v1.hasPairedKeyEncryption else { throw NearbyError.requiredFieldMissing }
|
||||
var pairedResult=Sharing_Nearby_Frame()
|
||||
pairedResult.version = .v1
|
||||
pairedResult.v1=Sharing_Nearby_V1Frame()
|
||||
pairedResult.v1.type = .pairedKeyResult
|
||||
pairedResult.v1.pairedKeyResult=Sharing_Nearby_PairedKeyResultFrame()
|
||||
pairedResult.v1.pairedKeyResult.status = .unable
|
||||
try sendTransferSetupFrame(pairedResult)
|
||||
currentState = .sentPairedKeyResult
|
||||
}
|
||||
|
||||
private func processPairedKeyResult(frame:Sharing_Nearby_Frame) throws{
|
||||
guard frame.hasV1, frame.v1.hasPairedKeyResult else { throw NearbyError.requiredFieldMissing }
|
||||
|
||||
var introduction=Sharing_Nearby_Frame()
|
||||
introduction.version = .v1
|
||||
introduction.v1.type = .introduction
|
||||
if urlsToSend.count==1 && urlsToSend[0].scheme != "file"{
|
||||
var meta=Sharing_Nearby_TextMetadata()
|
||||
meta.type = .url
|
||||
meta.textTitle=urlsToSend[0].host ?? "URL"
|
||||
meta.size=Int64(urlsToSend[0].absoluteString.utf8.count)
|
||||
meta.payloadID=Int64.random(in: Int64.min...Int64.max)
|
||||
introduction.v1.introduction.textMetadata.append(meta)
|
||||
}else{
|
||||
for url in urlsToSend{
|
||||
guard url.scheme=="file" else {continue}
|
||||
var meta=Sharing_Nearby_FileMetadata()
|
||||
meta.name=OutboundNearbyConnection.sanitizeFileName(name: url.lastPathComponent)
|
||||
let attrs=try FileManager.default.attributesOfItem(atPath: url.path)
|
||||
meta.size=(attrs[FileAttributeKey.size] as! NSNumber).int64Value
|
||||
let typeID=try? url.resourceValues(forKeys: [.typeIdentifierKey]).typeIdentifier
|
||||
meta.mimeType="application/octet-stream"
|
||||
if let typeID=typeID{
|
||||
let type=UTType(typeID)
|
||||
if let type=type, let mimeType=type.preferredMIMEType{
|
||||
meta.mimeType=mimeType
|
||||
}
|
||||
}
|
||||
if meta.mimeType.starts(with: "image/"){
|
||||
meta.type = .image
|
||||
}else if meta.mimeType.starts(with: "video/"){
|
||||
meta.type = .video
|
||||
}else if(meta.mimeType.starts(with: "audio/")){
|
||||
meta.type = .audio
|
||||
}else if(url.pathExtension.lowercased()=="apk"){
|
||||
meta.type = .app
|
||||
}else{
|
||||
meta.type = .unknown
|
||||
}
|
||||
meta.payloadID=Int64.random(in: Int64.min...Int64.max)
|
||||
queue.append(OutgoingFileTransfer(url: url, payloadID: meta.payloadID, handle: try FileHandle(forReadingFrom: url), totalBytes: meta.size, currentOffset: 0))
|
||||
introduction.v1.introduction.fileMetadata.append(meta)
|
||||
totalBytesToSend+=meta.size
|
||||
}
|
||||
}
|
||||
#if DEBUG
|
||||
print("sent introduction: \(introduction)")
|
||||
#endif
|
||||
try sendTransferSetupFrame(introduction)
|
||||
|
||||
currentState = .sentIntroduction
|
||||
}
|
||||
|
||||
private func processConsent(frame:Sharing_Nearby_Frame) throws{
|
||||
guard frame.version == .v1, frame.v1.type == .response else {throw NearbyError.requiredFieldMissing}
|
||||
switch frame.v1.connectionResponse.status{
|
||||
case .accept:
|
||||
currentState = .sendingFiles
|
||||
delegate?.outboundConnectionTransferAccepted(connection: self)
|
||||
try sendNextFileChunk()
|
||||
case .reject, .unknown:
|
||||
delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .userRejected))
|
||||
try sendDisconnectionAndDisconnect()
|
||||
case .notEnoughSpace:
|
||||
delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .notEnoughSpace))
|
||||
try sendDisconnectionAndDisconnect()
|
||||
case .timedOut:
|
||||
delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .timedOut))
|
||||
try sendDisconnectionAndDisconnect()
|
||||
case .unsupportedAttachmentType:
|
||||
delegate?.outboundConnection(connection: self, failedWithError: NearbyError.canceled(reason: .unsupportedType))
|
||||
try sendDisconnectionAndDisconnect()
|
||||
}
|
||||
}
|
||||
|
||||
private func sendNextFileChunk() throws{
|
||||
print("SEND NEXT: \(Thread.current)")
|
||||
if cancelled{
|
||||
return
|
||||
}
|
||||
if currentTransfer==nil || currentTransfer?.currentOffset==currentTransfer?.totalBytes{
|
||||
if currentTransfer != nil && currentTransfer?.handle != nil{
|
||||
try currentTransfer?.handle?.close()
|
||||
}
|
||||
if queue.isEmpty{
|
||||
#if DEBUG
|
||||
print("Disconnecting because all files have been transferred")
|
||||
#endif
|
||||
try sendDisconnectionAndDisconnect()
|
||||
delegate?.outboundConnectionTransferFinished(connection: self)
|
||||
return
|
||||
}
|
||||
currentTransfer=queue.removeFirst()
|
||||
}
|
||||
|
||||
guard let fileBuffer=try currentTransfer!.handle!.read(upToCount: 512*1024) else{
|
||||
throw NearbyError.inputOutput(cause: Errno.ioError)
|
||||
}
|
||||
|
||||
var transfer=Location_Nearby_Connections_PayloadTransferFrame()
|
||||
transfer.packetType = .data
|
||||
transfer.payloadChunk.offset=currentTransfer!.currentOffset
|
||||
transfer.payloadChunk.flags=0
|
||||
transfer.payloadChunk.body=fileBuffer
|
||||
transfer.payloadHeader.id=currentTransfer!.payloadID
|
||||
transfer.payloadHeader.type = .file
|
||||
transfer.payloadHeader.totalSize=Int64(currentTransfer!.totalBytes)
|
||||
transfer.payloadHeader.isSensitive=false
|
||||
currentTransfer!.currentOffset+=Int64(fileBuffer.count)
|
||||
|
||||
var wrapper=Location_Nearby_Connections_OfflineFrame()
|
||||
wrapper.version = .v1
|
||||
wrapper.v1=Location_Nearby_Connections_V1Frame()
|
||||
wrapper.v1.type = .payloadTransfer
|
||||
wrapper.v1.payloadTransfer=transfer
|
||||
try encryptAndSendOfflineFrame(wrapper, completion: {
|
||||
do{
|
||||
try self.sendNextFileChunk()
|
||||
}catch{
|
||||
self.lastError=error
|
||||
self.protocolError()
|
||||
}
|
||||
})
|
||||
#if DEBUG
|
||||
print("sent file chunk, current transfer: \(String(describing: currentTransfer))")
|
||||
#endif
|
||||
totalBytesSent+=Int64(fileBuffer.count)
|
||||
delegate?.outboundConnection(connection: self, transferProgress: Double(totalBytesSent)/Double(totalBytesToSend))
|
||||
|
||||
if currentTransfer!.currentOffset==currentTransfer!.totalBytes{
|
||||
// Signal end of file (yes, all this for one bit)
|
||||
var transfer=Location_Nearby_Connections_PayloadTransferFrame()
|
||||
transfer.packetType = .data
|
||||
transfer.payloadChunk.offset=currentTransfer!.currentOffset
|
||||
transfer.payloadChunk.flags=1 // <- this one here
|
||||
transfer.payloadHeader.id=currentTransfer!.payloadID
|
||||
transfer.payloadHeader.type = .file
|
||||
transfer.payloadHeader.totalSize=Int64(currentTransfer!.totalBytes)
|
||||
transfer.payloadHeader.isSensitive=false
|
||||
|
||||
var wrapper=Location_Nearby_Connections_OfflineFrame()
|
||||
wrapper.version = .v1
|
||||
wrapper.v1=Location_Nearby_Connections_V1Frame()
|
||||
wrapper.v1.type = .payloadTransfer
|
||||
wrapper.v1.payloadTransfer=transfer
|
||||
try encryptAndSendOfflineFrame(wrapper)
|
||||
#if DEBUG
|
||||
print("sent EOF, current transfer: \(String(describing: currentTransfer))")
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
private static func sanitizeFileName(name:String)->String{
|
||||
return name.replacingOccurrences(of: "[\\/\\\\?%\\*:\\|\"<>=]", with: "_", options: .regularExpression)
|
||||
}
|
||||
}
|
||||
|
||||
fileprivate struct OutgoingFileTransfer{
|
||||
let url:URL
|
||||
let payloadID:Int64
|
||||
let handle:FileHandle?
|
||||
let totalBytes:Int64
|
||||
var currentOffset:Int64
|
||||
}
|
||||
|
||||
protocol OutboundNearbyConnectionDelegate{
|
||||
func outboundConnectionWasEstablished(connection:OutboundNearbyConnection)
|
||||
func outboundConnection(connection:OutboundNearbyConnection, transferProgress:Double)
|
||||
func outboundConnectionTransferAccepted(connection:OutboundNearbyConnection)
|
||||
func outboundConnection(connection:OutboundNearbyConnection, failedWithError:Error)
|
||||
func outboundConnectionTransferFinished(connection:OutboundNearbyConnection)
|
||||
}
|
||||
540
NearbyShare/Protobuf/device_to_device_messages.pb.swift
Normal file
540
NearbyShare/Protobuf/device_to_device_messages.pb.swift
Normal file
@@ -0,0 +1,540 @@
|
||||
// DO NOT EDIT.
|
||||
// swift-format-ignore-file
|
||||
//
|
||||
// Generated by the Swift generator plugin for the protocol buffer compiler.
|
||||
// Source: device_to_device_messages.proto
|
||||
//
|
||||
// For information on using the generated types, please see the documentation:
|
||||
// https://github.com/apple/swift-protobuf/
|
||||
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import Foundation
|
||||
import SwiftProtobuf
|
||||
|
||||
// If the compiler emits an error on this type, it is because this file
|
||||
// was generated by a version of the `protoc` Swift plug-in that is
|
||||
// incompatible with the version of SwiftProtobuf to which you are linking.
|
||||
// Please ensure that you are building against the same version of the API
|
||||
// that was used to generate this file.
|
||||
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
|
||||
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
|
||||
typealias Version = _2
|
||||
}
|
||||
|
||||
/// Type of curve
|
||||
enum Securegcm_Curve: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
case ed25519 // = 1
|
||||
|
||||
init() {
|
||||
self = .ed25519
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 1: self = .ed25519
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .ed25519: return 1
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if swift(>=4.2)
|
||||
|
||||
extension Securegcm_Curve: CaseIterable {
|
||||
// Support synthesized by the compiler.
|
||||
}
|
||||
|
||||
#endif // swift(>=4.2)
|
||||
|
||||
/// Used by protocols between devices
|
||||
struct Securegcm_DeviceToDeviceMessage {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// the payload of the message
|
||||
var message: Data {
|
||||
get {return _message ?? Data()}
|
||||
set {_message = newValue}
|
||||
}
|
||||
/// Returns true if `message` has been explicitly set.
|
||||
var hasMessage: Bool {return self._message != nil}
|
||||
/// Clears the value of `message`. Subsequent reads from it will return its default value.
|
||||
mutating func clearMessage() {self._message = nil}
|
||||
|
||||
/// the sequence number of the message - must be increasing.
|
||||
var sequenceNumber: Int32 {
|
||||
get {return _sequenceNumber ?? 0}
|
||||
set {_sequenceNumber = newValue}
|
||||
}
|
||||
/// Returns true if `sequenceNumber` has been explicitly set.
|
||||
var hasSequenceNumber: Bool {return self._sequenceNumber != nil}
|
||||
/// Clears the value of `sequenceNumber`. Subsequent reads from it will return its default value.
|
||||
mutating func clearSequenceNumber() {self._sequenceNumber = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _message: Data? = nil
|
||||
fileprivate var _sequenceNumber: Int32? = nil
|
||||
}
|
||||
|
||||
/// sent as the first message from initiator to responder
|
||||
/// in an unauthenticated Diffie-Hellman Key Exchange
|
||||
struct Securegcm_InitiatorHello {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// The session public key to send to the responder
|
||||
var publicDhKey: Securemessage_GenericPublicKey {
|
||||
get {return _publicDhKey ?? Securemessage_GenericPublicKey()}
|
||||
set {_publicDhKey = newValue}
|
||||
}
|
||||
/// Returns true if `publicDhKey` has been explicitly set.
|
||||
var hasPublicDhKey: Bool {return self._publicDhKey != nil}
|
||||
/// Clears the value of `publicDhKey`. Subsequent reads from it will return its default value.
|
||||
mutating func clearPublicDhKey() {self._publicDhKey = nil}
|
||||
|
||||
/// The protocol version
|
||||
var protocolVersion: Int32 {
|
||||
get {return _protocolVersion ?? 0}
|
||||
set {_protocolVersion = newValue}
|
||||
}
|
||||
/// Returns true if `protocolVersion` has been explicitly set.
|
||||
var hasProtocolVersion: Bool {return self._protocolVersion != nil}
|
||||
/// Clears the value of `protocolVersion`. Subsequent reads from it will return its default value.
|
||||
mutating func clearProtocolVersion() {self._protocolVersion = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _publicDhKey: Securemessage_GenericPublicKey? = nil
|
||||
fileprivate var _protocolVersion: Int32? = nil
|
||||
}
|
||||
|
||||
/// sent inside the header of the first message from the responder to the
|
||||
/// initiator in an unauthenticated Diffie-Hellman Key Exchange
|
||||
struct Securegcm_ResponderHello {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// The session public key to send to the initiator
|
||||
var publicDhKey: Securemessage_GenericPublicKey {
|
||||
get {return _publicDhKey ?? Securemessage_GenericPublicKey()}
|
||||
set {_publicDhKey = newValue}
|
||||
}
|
||||
/// Returns true if `publicDhKey` has been explicitly set.
|
||||
var hasPublicDhKey: Bool {return self._publicDhKey != nil}
|
||||
/// Clears the value of `publicDhKey`. Subsequent reads from it will return its default value.
|
||||
mutating func clearPublicDhKey() {self._publicDhKey = nil}
|
||||
|
||||
/// The protocol version
|
||||
var protocolVersion: Int32 {
|
||||
get {return _protocolVersion ?? 0}
|
||||
set {_protocolVersion = newValue}
|
||||
}
|
||||
/// Returns true if `protocolVersion` has been explicitly set.
|
||||
var hasProtocolVersion: Bool {return self._protocolVersion != nil}
|
||||
/// Clears the value of `protocolVersion`. Subsequent reads from it will return its default value.
|
||||
mutating func clearProtocolVersion() {self._protocolVersion = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _publicDhKey: Securemessage_GenericPublicKey? = nil
|
||||
fileprivate var _protocolVersion: Int32? = nil
|
||||
}
|
||||
|
||||
/// A convenience proto for encoding curve points in affine representation
|
||||
struct Securegcm_EcPoint {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var curve: Securegcm_Curve {
|
||||
get {return _curve ?? .ed25519}
|
||||
set {_curve = newValue}
|
||||
}
|
||||
/// Returns true if `curve` has been explicitly set.
|
||||
var hasCurve: Bool {return self._curve != nil}
|
||||
/// Clears the value of `curve`. Subsequent reads from it will return its default value.
|
||||
mutating func clearCurve() {self._curve = nil}
|
||||
|
||||
/// x and y are encoded in big-endian two's complement
|
||||
/// client MUST verify (x,y) is a valid point on the specified curve
|
||||
var x: Data {
|
||||
get {return _x ?? Data()}
|
||||
set {_x = newValue}
|
||||
}
|
||||
/// Returns true if `x` has been explicitly set.
|
||||
var hasX: Bool {return self._x != nil}
|
||||
/// Clears the value of `x`. Subsequent reads from it will return its default value.
|
||||
mutating func clearX() {self._x = nil}
|
||||
|
||||
var y: Data {
|
||||
get {return _y ?? Data()}
|
||||
set {_y = newValue}
|
||||
}
|
||||
/// Returns true if `y` has been explicitly set.
|
||||
var hasY: Bool {return self._y != nil}
|
||||
/// Clears the value of `y`. Subsequent reads from it will return its default value.
|
||||
mutating func clearY() {self._y = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _curve: Securegcm_Curve? = nil
|
||||
fileprivate var _x: Data? = nil
|
||||
fileprivate var _y: Data? = nil
|
||||
}
|
||||
|
||||
struct Securegcm_SpakeHandshakeMessage {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// Each flow in the protocol bumps this counter
|
||||
var flowNumber: Int32 {
|
||||
get {return _flowNumber ?? 0}
|
||||
set {_flowNumber = newValue}
|
||||
}
|
||||
/// Returns true if `flowNumber` has been explicitly set.
|
||||
var hasFlowNumber: Bool {return self._flowNumber != nil}
|
||||
/// Clears the value of `flowNumber`. Subsequent reads from it will return its default value.
|
||||
mutating func clearFlowNumber() {self._flowNumber = nil}
|
||||
|
||||
/// Some (but not all) SPAKE flows send a point on an elliptic curve
|
||||
var ecPoint: Securegcm_EcPoint {
|
||||
get {return _ecPoint ?? Securegcm_EcPoint()}
|
||||
set {_ecPoint = newValue}
|
||||
}
|
||||
/// Returns true if `ecPoint` has been explicitly set.
|
||||
var hasEcPoint: Bool {return self._ecPoint != nil}
|
||||
/// Clears the value of `ecPoint`. Subsequent reads from it will return its default value.
|
||||
mutating func clearEcPoint() {self._ecPoint = nil}
|
||||
|
||||
/// Some (but not all) SPAKE flows send a hash value
|
||||
var hashValue_p: Data {
|
||||
get {return _hashValue_p ?? Data()}
|
||||
set {_hashValue_p = newValue}
|
||||
}
|
||||
/// Returns true if `hashValue_p` has been explicitly set.
|
||||
var hasHashValue_p: Bool {return self._hashValue_p != nil}
|
||||
/// Clears the value of `hashValue_p`. Subsequent reads from it will return its default value.
|
||||
mutating func clearHashValue_p() {self._hashValue_p = nil}
|
||||
|
||||
/// The last flow of a SPAKE protocol can send an optional payload,
|
||||
/// since the key exchange is already complete on the sender's side.
|
||||
var payload: Data {
|
||||
get {return _payload ?? Data()}
|
||||
set {_payload = newValue}
|
||||
}
|
||||
/// Returns true if `payload` has been explicitly set.
|
||||
var hasPayload: Bool {return self._payload != nil}
|
||||
/// Clears the value of `payload`. Subsequent reads from it will return its default value.
|
||||
mutating func clearPayload() {self._payload = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _flowNumber: Int32? = nil
|
||||
fileprivate var _ecPoint: Securegcm_EcPoint? = nil
|
||||
fileprivate var _hashValue_p: Data? = nil
|
||||
fileprivate var _payload: Data? = nil
|
||||
}
|
||||
|
||||
#if swift(>=5.5) && canImport(_Concurrency)
|
||||
extension Securegcm_Curve: @unchecked Sendable {}
|
||||
extension Securegcm_DeviceToDeviceMessage: @unchecked Sendable {}
|
||||
extension Securegcm_InitiatorHello: @unchecked Sendable {}
|
||||
extension Securegcm_ResponderHello: @unchecked Sendable {}
|
||||
extension Securegcm_EcPoint: @unchecked Sendable {}
|
||||
extension Securegcm_SpakeHandshakeMessage: @unchecked Sendable {}
|
||||
#endif // swift(>=5.5) && canImport(_Concurrency)
|
||||
|
||||
// MARK: - Code below here is support for the SwiftProtobuf runtime.
|
||||
|
||||
fileprivate let _protobuf_package = "securegcm"
|
||||
|
||||
extension Securegcm_Curve: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "ED_25519"),
|
||||
]
|
||||
}
|
||||
|
||||
extension Securegcm_DeviceToDeviceMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".DeviceToDeviceMessage"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "message"),
|
||||
2: .standard(proto: "sequence_number"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularBytesField(value: &self._message) }()
|
||||
case 2: try { try decoder.decodeSingularInt32Field(value: &self._sequenceNumber) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._message {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._sequenceNumber {
|
||||
try visitor.visitSingularInt32Field(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securegcm_DeviceToDeviceMessage, rhs: Securegcm_DeviceToDeviceMessage) -> Bool {
|
||||
if lhs._message != rhs._message {return false}
|
||||
if lhs._sequenceNumber != rhs._sequenceNumber {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securegcm_InitiatorHello: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".InitiatorHello"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "public_dh_key"),
|
||||
2: .standard(proto: "protocol_version"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if let v = self._publicDhKey, !v.isInitialized {return false}
|
||||
return true
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularMessageField(value: &self._publicDhKey) }()
|
||||
case 2: try { try decoder.decodeSingularInt32Field(value: &self._protocolVersion) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._publicDhKey {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._protocolVersion {
|
||||
try visitor.visitSingularInt32Field(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securegcm_InitiatorHello, rhs: Securegcm_InitiatorHello) -> Bool {
|
||||
if lhs._publicDhKey != rhs._publicDhKey {return false}
|
||||
if lhs._protocolVersion != rhs._protocolVersion {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securegcm_ResponderHello: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".ResponderHello"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "public_dh_key"),
|
||||
2: .standard(proto: "protocol_version"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if let v = self._publicDhKey, !v.isInitialized {return false}
|
||||
return true
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularMessageField(value: &self._publicDhKey) }()
|
||||
case 2: try { try decoder.decodeSingularInt32Field(value: &self._protocolVersion) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._publicDhKey {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._protocolVersion {
|
||||
try visitor.visitSingularInt32Field(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securegcm_ResponderHello, rhs: Securegcm_ResponderHello) -> Bool {
|
||||
if lhs._publicDhKey != rhs._publicDhKey {return false}
|
||||
if lhs._protocolVersion != rhs._protocolVersion {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securegcm_EcPoint: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".EcPoint"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "curve"),
|
||||
2: .same(proto: "x"),
|
||||
3: .same(proto: "y"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if self._curve == nil {return false}
|
||||
if self._x == nil {return false}
|
||||
if self._y == nil {return false}
|
||||
return true
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularEnumField(value: &self._curve) }()
|
||||
case 2: try { try decoder.decodeSingularBytesField(value: &self._x) }()
|
||||
case 3: try { try decoder.decodeSingularBytesField(value: &self._y) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._curve {
|
||||
try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._x {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try { if let v = self._y {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 3)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securegcm_EcPoint, rhs: Securegcm_EcPoint) -> Bool {
|
||||
if lhs._curve != rhs._curve {return false}
|
||||
if lhs._x != rhs._x {return false}
|
||||
if lhs._y != rhs._y {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securegcm_SpakeHandshakeMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".SpakeHandshakeMessage"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "flow_number"),
|
||||
2: .standard(proto: "ec_point"),
|
||||
3: .standard(proto: "hash_value"),
|
||||
4: .same(proto: "payload"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if let v = self._ecPoint, !v.isInitialized {return false}
|
||||
return true
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularInt32Field(value: &self._flowNumber) }()
|
||||
case 2: try { try decoder.decodeSingularMessageField(value: &self._ecPoint) }()
|
||||
case 3: try { try decoder.decodeSingularBytesField(value: &self._hashValue_p) }()
|
||||
case 4: try { try decoder.decodeSingularBytesField(value: &self._payload) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._flowNumber {
|
||||
try visitor.visitSingularInt32Field(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._ecPoint {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try { if let v = self._hashValue_p {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 3)
|
||||
} }()
|
||||
try { if let v = self._payload {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 4)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securegcm_SpakeHandshakeMessage, rhs: Securegcm_SpakeHandshakeMessage) -> Bool {
|
||||
if lhs._flowNumber != rhs._flowNumber {return false}
|
||||
if lhs._ecPoint != rhs._ecPoint {return false}
|
||||
if lhs._hashValue_p != rhs._hashValue_p {return false}
|
||||
if lhs._payload != rhs._payload {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
3653
NearbyShare/Protobuf/offline_wire_formats.pb.swift
Normal file
3653
NearbyShare/Protobuf/offline_wire_formats.pb.swift
Normal file
File diff suppressed because it is too large
Load Diff
1522
NearbyShare/Protobuf/securegcm.pb.swift
Normal file
1522
NearbyShare/Protobuf/securegcm.pb.swift
Normal file
File diff suppressed because it is too large
Load Diff
951
NearbyShare/Protobuf/securemessage.pb.swift
Normal file
951
NearbyShare/Protobuf/securemessage.pb.swift
Normal file
@@ -0,0 +1,951 @@
|
||||
// DO NOT EDIT.
|
||||
// swift-format-ignore-file
|
||||
//
|
||||
// Generated by the Swift generator plugin for the protocol buffer compiler.
|
||||
// Source: securemessage.proto
|
||||
//
|
||||
// For information on using the generated types, please see the documentation:
|
||||
// https://github.com/apple/swift-protobuf/
|
||||
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Proto definitions for SecureMessage format
|
||||
|
||||
import Foundation
|
||||
import SwiftProtobuf
|
||||
|
||||
// If the compiler emits an error on this type, it is because this file
|
||||
// was generated by a version of the `protoc` Swift plug-in that is
|
||||
// incompatible with the version of SwiftProtobuf to which you are linking.
|
||||
// Please ensure that you are building against the same version of the API
|
||||
// that was used to generate this file.
|
||||
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
|
||||
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
|
||||
typealias Version = _2
|
||||
}
|
||||
|
||||
/// Supported "signature" schemes (both symmetric key and public key based)
|
||||
enum Securemessage_SigScheme: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
case hmacSha256 // = 1
|
||||
case ecdsaP256Sha256 // = 2
|
||||
|
||||
/// Not recommended -- use ECDSA_P256_SHA256 instead
|
||||
case rsa2048Sha256 // = 3
|
||||
|
||||
init() {
|
||||
self = .hmacSha256
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 1: self = .hmacSha256
|
||||
case 2: self = .ecdsaP256Sha256
|
||||
case 3: self = .rsa2048Sha256
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .hmacSha256: return 1
|
||||
case .ecdsaP256Sha256: return 2
|
||||
case .rsa2048Sha256: return 3
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if swift(>=4.2)
|
||||
|
||||
extension Securemessage_SigScheme: CaseIterable {
|
||||
// Support synthesized by the compiler.
|
||||
}
|
||||
|
||||
#endif // swift(>=4.2)
|
||||
|
||||
/// Supported encryption schemes
|
||||
enum Securemessage_EncScheme: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
|
||||
/// No encryption
|
||||
case none // = 1
|
||||
case aes256Cbc // = 2
|
||||
|
||||
init() {
|
||||
self = .none
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 1: self = .none
|
||||
case 2: self = .aes256Cbc
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .none: return 1
|
||||
case .aes256Cbc: return 2
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if swift(>=4.2)
|
||||
|
||||
extension Securemessage_EncScheme: CaseIterable {
|
||||
// Support synthesized by the compiler.
|
||||
}
|
||||
|
||||
#endif // swift(>=4.2)
|
||||
|
||||
/// A list of supported public key types
|
||||
enum Securemessage_PublicKeyType: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
case ecP256 // = 1
|
||||
case rsa2048 // = 2
|
||||
|
||||
/// 2048-bit MODP group 14, from RFC 3526
|
||||
case dh2048Modp // = 3
|
||||
|
||||
init() {
|
||||
self = .ecP256
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 1: self = .ecP256
|
||||
case 2: self = .rsa2048
|
||||
case 3: self = .dh2048Modp
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .ecP256: return 1
|
||||
case .rsa2048: return 2
|
||||
case .dh2048Modp: return 3
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if swift(>=4.2)
|
||||
|
||||
extension Securemessage_PublicKeyType: CaseIterable {
|
||||
// Support synthesized by the compiler.
|
||||
}
|
||||
|
||||
#endif // swift(>=4.2)
|
||||
|
||||
struct Securemessage_SecureMessage {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// Must contain a HeaderAndBody message
|
||||
var headerAndBody: Data {
|
||||
get {return _headerAndBody ?? Data()}
|
||||
set {_headerAndBody = newValue}
|
||||
}
|
||||
/// Returns true if `headerAndBody` has been explicitly set.
|
||||
var hasHeaderAndBody: Bool {return self._headerAndBody != nil}
|
||||
/// Clears the value of `headerAndBody`. Subsequent reads from it will return its default value.
|
||||
mutating func clearHeaderAndBody() {self._headerAndBody = nil}
|
||||
|
||||
/// Signature of header_and_body
|
||||
var signature: Data {
|
||||
get {return _signature ?? Data()}
|
||||
set {_signature = newValue}
|
||||
}
|
||||
/// Returns true if `signature` has been explicitly set.
|
||||
var hasSignature: Bool {return self._signature != nil}
|
||||
/// Clears the value of `signature`. Subsequent reads from it will return its default value.
|
||||
mutating func clearSignature() {self._signature = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _headerAndBody: Data? = nil
|
||||
fileprivate var _signature: Data? = nil
|
||||
}
|
||||
|
||||
struct Securemessage_Header {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var signatureScheme: Securemessage_SigScheme {
|
||||
get {return _signatureScheme ?? .hmacSha256}
|
||||
set {_signatureScheme = newValue}
|
||||
}
|
||||
/// Returns true if `signatureScheme` has been explicitly set.
|
||||
var hasSignatureScheme: Bool {return self._signatureScheme != nil}
|
||||
/// Clears the value of `signatureScheme`. Subsequent reads from it will return its default value.
|
||||
mutating func clearSignatureScheme() {self._signatureScheme = nil}
|
||||
|
||||
var encryptionScheme: Securemessage_EncScheme {
|
||||
get {return _encryptionScheme ?? .none}
|
||||
set {_encryptionScheme = newValue}
|
||||
}
|
||||
/// Returns true if `encryptionScheme` has been explicitly set.
|
||||
var hasEncryptionScheme: Bool {return self._encryptionScheme != nil}
|
||||
/// Clears the value of `encryptionScheme`. Subsequent reads from it will return its default value.
|
||||
mutating func clearEncryptionScheme() {self._encryptionScheme = nil}
|
||||
|
||||
/// Identifies the verification key
|
||||
var verificationKeyID: Data {
|
||||
get {return _verificationKeyID ?? Data()}
|
||||
set {_verificationKeyID = newValue}
|
||||
}
|
||||
/// Returns true if `verificationKeyID` has been explicitly set.
|
||||
var hasVerificationKeyID: Bool {return self._verificationKeyID != nil}
|
||||
/// Clears the value of `verificationKeyID`. Subsequent reads from it will return its default value.
|
||||
mutating func clearVerificationKeyID() {self._verificationKeyID = nil}
|
||||
|
||||
/// Identifies the decryption key
|
||||
var decryptionKeyID: Data {
|
||||
get {return _decryptionKeyID ?? Data()}
|
||||
set {_decryptionKeyID = newValue}
|
||||
}
|
||||
/// Returns true if `decryptionKeyID` has been explicitly set.
|
||||
var hasDecryptionKeyID: Bool {return self._decryptionKeyID != nil}
|
||||
/// Clears the value of `decryptionKeyID`. Subsequent reads from it will return its default value.
|
||||
mutating func clearDecryptionKeyID() {self._decryptionKeyID = nil}
|
||||
|
||||
/// Encryption may use an IV
|
||||
var iv: Data {
|
||||
get {return _iv ?? Data()}
|
||||
set {_iv = newValue}
|
||||
}
|
||||
/// Returns true if `iv` has been explicitly set.
|
||||
var hasIv: Bool {return self._iv != nil}
|
||||
/// Clears the value of `iv`. Subsequent reads from it will return its default value.
|
||||
mutating func clearIv() {self._iv = nil}
|
||||
|
||||
/// Arbitrary per-protocol public data, to be sent with the plain-text header
|
||||
var publicMetadata: Data {
|
||||
get {return _publicMetadata ?? Data()}
|
||||
set {_publicMetadata = newValue}
|
||||
}
|
||||
/// Returns true if `publicMetadata` has been explicitly set.
|
||||
var hasPublicMetadata: Bool {return self._publicMetadata != nil}
|
||||
/// Clears the value of `publicMetadata`. Subsequent reads from it will return its default value.
|
||||
mutating func clearPublicMetadata() {self._publicMetadata = nil}
|
||||
|
||||
/// The length of some associated data this is not sent in this SecureMessage,
|
||||
/// but which will be bound to the signature.
|
||||
var associatedDataLength: UInt32 {
|
||||
get {return _associatedDataLength ?? 0}
|
||||
set {_associatedDataLength = newValue}
|
||||
}
|
||||
/// Returns true if `associatedDataLength` has been explicitly set.
|
||||
var hasAssociatedDataLength: Bool {return self._associatedDataLength != nil}
|
||||
/// Clears the value of `associatedDataLength`. Subsequent reads from it will return its default value.
|
||||
mutating func clearAssociatedDataLength() {self._associatedDataLength = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _signatureScheme: Securemessage_SigScheme? = nil
|
||||
fileprivate var _encryptionScheme: Securemessage_EncScheme? = nil
|
||||
fileprivate var _verificationKeyID: Data? = nil
|
||||
fileprivate var _decryptionKeyID: Data? = nil
|
||||
fileprivate var _iv: Data? = nil
|
||||
fileprivate var _publicMetadata: Data? = nil
|
||||
fileprivate var _associatedDataLength: UInt32? = nil
|
||||
}
|
||||
|
||||
struct Securemessage_HeaderAndBody {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// Public data about this message (to be bound in the signature)
|
||||
var header: Securemessage_Header {
|
||||
get {return _header ?? Securemessage_Header()}
|
||||
set {_header = newValue}
|
||||
}
|
||||
/// Returns true if `header` has been explicitly set.
|
||||
var hasHeader: Bool {return self._header != nil}
|
||||
/// Clears the value of `header`. Subsequent reads from it will return its default value.
|
||||
mutating func clearHeader() {self._header = nil}
|
||||
|
||||
/// Payload data
|
||||
var body: Data {
|
||||
get {return _body ?? Data()}
|
||||
set {_body = newValue}
|
||||
}
|
||||
/// Returns true if `body` has been explicitly set.
|
||||
var hasBody: Bool {return self._body != nil}
|
||||
/// Clears the value of `body`. Subsequent reads from it will return its default value.
|
||||
mutating func clearBody() {self._body = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _header: Securemessage_Header? = nil
|
||||
fileprivate var _body: Data? = nil
|
||||
}
|
||||
|
||||
/// Must be kept wire-format compatible with HeaderAndBody. Provides the
|
||||
/// SecureMessage code with a consistent wire-format representation that
|
||||
/// remains stable irrespective of protobuf implementation choices. This
|
||||
/// low-level representation of a HeaderAndBody should not be used by
|
||||
/// any code outside of the SecureMessage library implementation/tests.
|
||||
struct Securemessage_HeaderAndBodyInternal {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// A raw (wire-format) byte encoding of a Header, suitable for hashing
|
||||
var header: Data {
|
||||
get {return _header ?? Data()}
|
||||
set {_header = newValue}
|
||||
}
|
||||
/// Returns true if `header` has been explicitly set.
|
||||
var hasHeader: Bool {return self._header != nil}
|
||||
/// Clears the value of `header`. Subsequent reads from it will return its default value.
|
||||
mutating func clearHeader() {self._header = nil}
|
||||
|
||||
/// Payload data
|
||||
var body: Data {
|
||||
get {return _body ?? Data()}
|
||||
set {_body = newValue}
|
||||
}
|
||||
/// Returns true if `body` has been explicitly set.
|
||||
var hasBody: Bool {return self._body != nil}
|
||||
/// Clears the value of `body`. Subsequent reads from it will return its default value.
|
||||
mutating func clearBody() {self._body = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _header: Data? = nil
|
||||
fileprivate var _body: Data? = nil
|
||||
}
|
||||
|
||||
/// A convenience proto for encoding NIST P-256 elliptic curve public keys
|
||||
struct Securemessage_EcP256PublicKey {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// x and y are encoded in big-endian two's complement (slightly wasteful)
|
||||
/// Client MUST verify (x,y) is a valid point on NIST P256
|
||||
var x: Data {
|
||||
get {return _x ?? Data()}
|
||||
set {_x = newValue}
|
||||
}
|
||||
/// Returns true if `x` has been explicitly set.
|
||||
var hasX: Bool {return self._x != nil}
|
||||
/// Clears the value of `x`. Subsequent reads from it will return its default value.
|
||||
mutating func clearX() {self._x = nil}
|
||||
|
||||
var y: Data {
|
||||
get {return _y ?? Data()}
|
||||
set {_y = newValue}
|
||||
}
|
||||
/// Returns true if `y` has been explicitly set.
|
||||
var hasY: Bool {return self._y != nil}
|
||||
/// Clears the value of `y`. Subsequent reads from it will return its default value.
|
||||
mutating func clearY() {self._y = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _x: Data? = nil
|
||||
fileprivate var _y: Data? = nil
|
||||
}
|
||||
|
||||
/// A convenience proto for encoding RSA public keys with small exponents
|
||||
struct Securemessage_SimpleRsaPublicKey {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// Encoded in big-endian two's complement
|
||||
var n: Data {
|
||||
get {return _n ?? Data()}
|
||||
set {_n = newValue}
|
||||
}
|
||||
/// Returns true if `n` has been explicitly set.
|
||||
var hasN: Bool {return self._n != nil}
|
||||
/// Clears the value of `n`. Subsequent reads from it will return its default value.
|
||||
mutating func clearN() {self._n = nil}
|
||||
|
||||
var e: Int32 {
|
||||
get {return _e ?? 65537}
|
||||
set {_e = newValue}
|
||||
}
|
||||
/// Returns true if `e` has been explicitly set.
|
||||
var hasE: Bool {return self._e != nil}
|
||||
/// Clears the value of `e`. Subsequent reads from it will return its default value.
|
||||
mutating func clearE() {self._e = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _n: Data? = nil
|
||||
fileprivate var _e: Int32? = nil
|
||||
}
|
||||
|
||||
/// A convenience proto for encoding Diffie-Hellman public keys,
|
||||
/// for use only when Elliptic Curve based key exchanges are not possible.
|
||||
/// (Note that the group parameters must be specified separately)
|
||||
struct Securemessage_DhPublicKey {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// Big-endian two's complement encoded group element
|
||||
var y: Data {
|
||||
get {return _y ?? Data()}
|
||||
set {_y = newValue}
|
||||
}
|
||||
/// Returns true if `y` has been explicitly set.
|
||||
var hasY: Bool {return self._y != nil}
|
||||
/// Clears the value of `y`. Subsequent reads from it will return its default value.
|
||||
mutating func clearY() {self._y = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _y: Data? = nil
|
||||
}
|
||||
|
||||
struct Securemessage_GenericPublicKey {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var type: Securemessage_PublicKeyType {
|
||||
get {return _type ?? .ecP256}
|
||||
set {_type = newValue}
|
||||
}
|
||||
/// Returns true if `type` has been explicitly set.
|
||||
var hasType: Bool {return self._type != nil}
|
||||
/// Clears the value of `type`. Subsequent reads from it will return its default value.
|
||||
mutating func clearType() {self._type = nil}
|
||||
|
||||
var ecP256PublicKey: Securemessage_EcP256PublicKey {
|
||||
get {return _ecP256PublicKey ?? Securemessage_EcP256PublicKey()}
|
||||
set {_ecP256PublicKey = newValue}
|
||||
}
|
||||
/// Returns true if `ecP256PublicKey` has been explicitly set.
|
||||
var hasEcP256PublicKey: Bool {return self._ecP256PublicKey != nil}
|
||||
/// Clears the value of `ecP256PublicKey`. Subsequent reads from it will return its default value.
|
||||
mutating func clearEcP256PublicKey() {self._ecP256PublicKey = nil}
|
||||
|
||||
var rsa2048PublicKey: Securemessage_SimpleRsaPublicKey {
|
||||
get {return _rsa2048PublicKey ?? Securemessage_SimpleRsaPublicKey()}
|
||||
set {_rsa2048PublicKey = newValue}
|
||||
}
|
||||
/// Returns true if `rsa2048PublicKey` has been explicitly set.
|
||||
var hasRsa2048PublicKey: Bool {return self._rsa2048PublicKey != nil}
|
||||
/// Clears the value of `rsa2048PublicKey`. Subsequent reads from it will return its default value.
|
||||
mutating func clearRsa2048PublicKey() {self._rsa2048PublicKey = nil}
|
||||
|
||||
/// Use only as a last resort
|
||||
var dh2048PublicKey: Securemessage_DhPublicKey {
|
||||
get {return _dh2048PublicKey ?? Securemessage_DhPublicKey()}
|
||||
set {_dh2048PublicKey = newValue}
|
||||
}
|
||||
/// Returns true if `dh2048PublicKey` has been explicitly set.
|
||||
var hasDh2048PublicKey: Bool {return self._dh2048PublicKey != nil}
|
||||
/// Clears the value of `dh2048PublicKey`. Subsequent reads from it will return its default value.
|
||||
mutating func clearDh2048PublicKey() {self._dh2048PublicKey = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _type: Securemessage_PublicKeyType? = nil
|
||||
fileprivate var _ecP256PublicKey: Securemessage_EcP256PublicKey? = nil
|
||||
fileprivate var _rsa2048PublicKey: Securemessage_SimpleRsaPublicKey? = nil
|
||||
fileprivate var _dh2048PublicKey: Securemessage_DhPublicKey? = nil
|
||||
}
|
||||
|
||||
#if swift(>=5.5) && canImport(_Concurrency)
|
||||
extension Securemessage_SigScheme: @unchecked Sendable {}
|
||||
extension Securemessage_EncScheme: @unchecked Sendable {}
|
||||
extension Securemessage_PublicKeyType: @unchecked Sendable {}
|
||||
extension Securemessage_SecureMessage: @unchecked Sendable {}
|
||||
extension Securemessage_Header: @unchecked Sendable {}
|
||||
extension Securemessage_HeaderAndBody: @unchecked Sendable {}
|
||||
extension Securemessage_HeaderAndBodyInternal: @unchecked Sendable {}
|
||||
extension Securemessage_EcP256PublicKey: @unchecked Sendable {}
|
||||
extension Securemessage_SimpleRsaPublicKey: @unchecked Sendable {}
|
||||
extension Securemessage_DhPublicKey: @unchecked Sendable {}
|
||||
extension Securemessage_GenericPublicKey: @unchecked Sendable {}
|
||||
#endif // swift(>=5.5) && canImport(_Concurrency)
|
||||
|
||||
// MARK: - Code below here is support for the SwiftProtobuf runtime.
|
||||
|
||||
fileprivate let _protobuf_package = "securemessage"
|
||||
|
||||
extension Securemessage_SigScheme: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "HMAC_SHA256"),
|
||||
2: .same(proto: "ECDSA_P256_SHA256"),
|
||||
3: .same(proto: "RSA2048_SHA256"),
|
||||
]
|
||||
}
|
||||
|
||||
extension Securemessage_EncScheme: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "NONE"),
|
||||
2: .same(proto: "AES_256_CBC"),
|
||||
]
|
||||
}
|
||||
|
||||
extension Securemessage_PublicKeyType: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "EC_P256"),
|
||||
2: .same(proto: "RSA2048"),
|
||||
3: .same(proto: "DH2048_MODP"),
|
||||
]
|
||||
}
|
||||
|
||||
extension Securemessage_SecureMessage: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".SecureMessage"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "header_and_body"),
|
||||
2: .same(proto: "signature"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if self._headerAndBody == nil {return false}
|
||||
if self._signature == nil {return false}
|
||||
return true
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularBytesField(value: &self._headerAndBody) }()
|
||||
case 2: try { try decoder.decodeSingularBytesField(value: &self._signature) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._headerAndBody {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._signature {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securemessage_SecureMessage, rhs: Securemessage_SecureMessage) -> Bool {
|
||||
if lhs._headerAndBody != rhs._headerAndBody {return false}
|
||||
if lhs._signature != rhs._signature {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securemessage_Header: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".Header"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "signature_scheme"),
|
||||
2: .standard(proto: "encryption_scheme"),
|
||||
3: .standard(proto: "verification_key_id"),
|
||||
4: .standard(proto: "decryption_key_id"),
|
||||
5: .same(proto: "iv"),
|
||||
6: .standard(proto: "public_metadata"),
|
||||
7: .standard(proto: "associated_data_length"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if self._signatureScheme == nil {return false}
|
||||
if self._encryptionScheme == nil {return false}
|
||||
return true
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularEnumField(value: &self._signatureScheme) }()
|
||||
case 2: try { try decoder.decodeSingularEnumField(value: &self._encryptionScheme) }()
|
||||
case 3: try { try decoder.decodeSingularBytesField(value: &self._verificationKeyID) }()
|
||||
case 4: try { try decoder.decodeSingularBytesField(value: &self._decryptionKeyID) }()
|
||||
case 5: try { try decoder.decodeSingularBytesField(value: &self._iv) }()
|
||||
case 6: try { try decoder.decodeSingularBytesField(value: &self._publicMetadata) }()
|
||||
case 7: try { try decoder.decodeSingularUInt32Field(value: &self._associatedDataLength) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._signatureScheme {
|
||||
try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._encryptionScheme {
|
||||
try visitor.visitSingularEnumField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try { if let v = self._verificationKeyID {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 3)
|
||||
} }()
|
||||
try { if let v = self._decryptionKeyID {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 4)
|
||||
} }()
|
||||
try { if let v = self._iv {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 5)
|
||||
} }()
|
||||
try { if let v = self._publicMetadata {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 6)
|
||||
} }()
|
||||
try { if let v = self._associatedDataLength {
|
||||
try visitor.visitSingularUInt32Field(value: v, fieldNumber: 7)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securemessage_Header, rhs: Securemessage_Header) -> Bool {
|
||||
if lhs._signatureScheme != rhs._signatureScheme {return false}
|
||||
if lhs._encryptionScheme != rhs._encryptionScheme {return false}
|
||||
if lhs._verificationKeyID != rhs._verificationKeyID {return false}
|
||||
if lhs._decryptionKeyID != rhs._decryptionKeyID {return false}
|
||||
if lhs._iv != rhs._iv {return false}
|
||||
if lhs._publicMetadata != rhs._publicMetadata {return false}
|
||||
if lhs._associatedDataLength != rhs._associatedDataLength {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securemessage_HeaderAndBody: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".HeaderAndBody"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "header"),
|
||||
2: .same(proto: "body"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if self._header == nil {return false}
|
||||
if self._body == nil {return false}
|
||||
if let v = self._header, !v.isInitialized {return false}
|
||||
return true
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularMessageField(value: &self._header) }()
|
||||
case 2: try { try decoder.decodeSingularBytesField(value: &self._body) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._header {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._body {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securemessage_HeaderAndBody, rhs: Securemessage_HeaderAndBody) -> Bool {
|
||||
if lhs._header != rhs._header {return false}
|
||||
if lhs._body != rhs._body {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securemessage_HeaderAndBodyInternal: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".HeaderAndBodyInternal"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "header"),
|
||||
2: .same(proto: "body"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if self._header == nil {return false}
|
||||
if self._body == nil {return false}
|
||||
return true
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularBytesField(value: &self._header) }()
|
||||
case 2: try { try decoder.decodeSingularBytesField(value: &self._body) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._header {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._body {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securemessage_HeaderAndBodyInternal, rhs: Securemessage_HeaderAndBodyInternal) -> Bool {
|
||||
if lhs._header != rhs._header {return false}
|
||||
if lhs._body != rhs._body {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securemessage_EcP256PublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".EcP256PublicKey"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "x"),
|
||||
2: .same(proto: "y"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if self._x == nil {return false}
|
||||
if self._y == nil {return false}
|
||||
return true
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularBytesField(value: &self._x) }()
|
||||
case 2: try { try decoder.decodeSingularBytesField(value: &self._y) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._x {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._y {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securemessage_EcP256PublicKey, rhs: Securemessage_EcP256PublicKey) -> Bool {
|
||||
if lhs._x != rhs._x {return false}
|
||||
if lhs._y != rhs._y {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securemessage_SimpleRsaPublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".SimpleRsaPublicKey"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "n"),
|
||||
2: .same(proto: "e"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if self._n == nil {return false}
|
||||
return true
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularBytesField(value: &self._n) }()
|
||||
case 2: try { try decoder.decodeSingularInt32Field(value: &self._e) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._n {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._e {
|
||||
try visitor.visitSingularInt32Field(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securemessage_SimpleRsaPublicKey, rhs: Securemessage_SimpleRsaPublicKey) -> Bool {
|
||||
if lhs._n != rhs._n {return false}
|
||||
if lhs._e != rhs._e {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securemessage_DhPublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".DhPublicKey"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "y"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if self._y == nil {return false}
|
||||
return true
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularBytesField(value: &self._y) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._y {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securemessage_DhPublicKey, rhs: Securemessage_DhPublicKey) -> Bool {
|
||||
if lhs._y != rhs._y {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securemessage_GenericPublicKey: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".GenericPublicKey"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "type"),
|
||||
2: .standard(proto: "ec_p256_public_key"),
|
||||
3: .standard(proto: "rsa2048_public_key"),
|
||||
4: .standard(proto: "dh2048_public_key"),
|
||||
]
|
||||
|
||||
public var isInitialized: Bool {
|
||||
if self._type == nil {return false}
|
||||
if let v = self._ecP256PublicKey, !v.isInitialized {return false}
|
||||
if let v = self._rsa2048PublicKey, !v.isInitialized {return false}
|
||||
if let v = self._dh2048PublicKey, !v.isInitialized {return false}
|
||||
return true
|
||||
}
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularEnumField(value: &self._type) }()
|
||||
case 2: try { try decoder.decodeSingularMessageField(value: &self._ecP256PublicKey) }()
|
||||
case 3: try { try decoder.decodeSingularMessageField(value: &self._rsa2048PublicKey) }()
|
||||
case 4: try { try decoder.decodeSingularMessageField(value: &self._dh2048PublicKey) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._type {
|
||||
try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._ecP256PublicKey {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try { if let v = self._rsa2048PublicKey {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 3)
|
||||
} }()
|
||||
try { if let v = self._dh2048PublicKey {
|
||||
try visitor.visitSingularMessageField(value: v, fieldNumber: 4)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securemessage_GenericPublicKey, rhs: Securemessage_GenericPublicKey) -> Bool {
|
||||
if lhs._type != rhs._type {return false}
|
||||
if lhs._ecP256PublicKey != rhs._ecP256PublicKey {return false}
|
||||
if lhs._rsa2048PublicKey != rhs._rsa2048PublicKey {return false}
|
||||
if lhs._dh2048PublicKey != rhs._dh2048PublicKey {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
735
NearbyShare/Protobuf/ukey.pb.swift
Normal file
735
NearbyShare/Protobuf/ukey.pb.swift
Normal file
@@ -0,0 +1,735 @@
|
||||
// DO NOT EDIT.
|
||||
// swift-format-ignore-file
|
||||
//
|
||||
// Generated by the Swift generator plugin for the protocol buffer compiler.
|
||||
// Source: ukey.proto
|
||||
//
|
||||
// For information on using the generated types, please see the documentation:
|
||||
// https://github.com/apple/swift-protobuf/
|
||||
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
import Foundation
|
||||
import SwiftProtobuf
|
||||
|
||||
// If the compiler emits an error on this type, it is because this file
|
||||
// was generated by a version of the `protoc` Swift plug-in that is
|
||||
// incompatible with the version of SwiftProtobuf to which you are linking.
|
||||
// Please ensure that you are building against the same version of the API
|
||||
// that was used to generate this file.
|
||||
fileprivate struct _GeneratedWithProtocGenSwiftVersion: SwiftProtobuf.ProtobufAPIVersionCheck {
|
||||
struct _2: SwiftProtobuf.ProtobufAPIVersion_2 {}
|
||||
typealias Version = _2
|
||||
}
|
||||
|
||||
enum Securegcm_Ukey2HandshakeCipher: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
case reserved // = 0
|
||||
|
||||
/// NIST P-256 used for ECDH, SHA512 used for
|
||||
case p256Sha512 // = 100
|
||||
|
||||
/// commitment
|
||||
case curve25519Sha512 // = 200
|
||||
|
||||
init() {
|
||||
self = .reserved
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .reserved
|
||||
case 100: self = .p256Sha512
|
||||
case 200: self = .curve25519Sha512
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .reserved: return 0
|
||||
case .p256Sha512: return 100
|
||||
case .curve25519Sha512: return 200
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
#if swift(>=4.2)
|
||||
|
||||
extension Securegcm_Ukey2HandshakeCipher: CaseIterable {
|
||||
// Support synthesized by the compiler.
|
||||
}
|
||||
|
||||
#endif // swift(>=4.2)
|
||||
|
||||
struct Securegcm_Ukey2Message {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// Identifies message type
|
||||
var messageType: Securegcm_Ukey2Message.TypeEnum {
|
||||
get {return _messageType ?? .unknownDoNotUse}
|
||||
set {_messageType = newValue}
|
||||
}
|
||||
/// Returns true if `messageType` has been explicitly set.
|
||||
var hasMessageType: Bool {return self._messageType != nil}
|
||||
/// Clears the value of `messageType`. Subsequent reads from it will return its default value.
|
||||
mutating func clearMessageType() {self._messageType = nil}
|
||||
|
||||
/// Actual message, to be parsed according to
|
||||
var messageData: Data {
|
||||
get {return _messageData ?? Data()}
|
||||
set {_messageData = newValue}
|
||||
}
|
||||
/// Returns true if `messageData` has been explicitly set.
|
||||
var hasMessageData: Bool {return self._messageData != nil}
|
||||
/// Clears the value of `messageData`. Subsequent reads from it will return its default value.
|
||||
mutating func clearMessageData() {self._messageData = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
enum TypeEnum: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
case unknownDoNotUse // = 0
|
||||
case alert // = 1
|
||||
case clientInit // = 2
|
||||
case serverInit // = 3
|
||||
case clientFinish // = 4
|
||||
|
||||
init() {
|
||||
self = .unknownDoNotUse
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 0: self = .unknownDoNotUse
|
||||
case 1: self = .alert
|
||||
case 2: self = .clientInit
|
||||
case 3: self = .serverInit
|
||||
case 4: self = .clientFinish
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .unknownDoNotUse: return 0
|
||||
case .alert: return 1
|
||||
case .clientInit: return 2
|
||||
case .serverInit: return 3
|
||||
case .clientFinish: return 4
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _messageType: Securegcm_Ukey2Message.TypeEnum? = nil
|
||||
fileprivate var _messageData: Data? = nil
|
||||
}
|
||||
|
||||
#if swift(>=4.2)
|
||||
|
||||
extension Securegcm_Ukey2Message.TypeEnum: CaseIterable {
|
||||
// Support synthesized by the compiler.
|
||||
}
|
||||
|
||||
#endif // swift(>=4.2)
|
||||
|
||||
struct Securegcm_Ukey2Alert {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var type: Securegcm_Ukey2Alert.AlertType {
|
||||
get {return _type ?? .badMessage}
|
||||
set {_type = newValue}
|
||||
}
|
||||
/// Returns true if `type` has been explicitly set.
|
||||
var hasType: Bool {return self._type != nil}
|
||||
/// Clears the value of `type`. Subsequent reads from it will return its default value.
|
||||
mutating func clearType() {self._type = nil}
|
||||
|
||||
var errorMessage: String {
|
||||
get {return _errorMessage ?? String()}
|
||||
set {_errorMessage = newValue}
|
||||
}
|
||||
/// Returns true if `errorMessage` has been explicitly set.
|
||||
var hasErrorMessage: Bool {return self._errorMessage != nil}
|
||||
/// Clears the value of `errorMessage`. Subsequent reads from it will return its default value.
|
||||
mutating func clearErrorMessage() {self._errorMessage = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
enum AlertType: SwiftProtobuf.Enum {
|
||||
typealias RawValue = Int
|
||||
|
||||
/// Framing errors
|
||||
case badMessage // = 1
|
||||
|
||||
/// message_type has an undefined value
|
||||
case badMessageType // = 2
|
||||
|
||||
/// message_type received does not correspond to
|
||||
case incorrectMessage // = 3
|
||||
|
||||
/// expected type at this stage of the protocol
|
||||
case badMessageData // = 4
|
||||
|
||||
/// ClientInit and ServerInit errors
|
||||
case badVersion // = 100
|
||||
|
||||
/// suitable version to speak with client.
|
||||
case badRandom // = 101
|
||||
|
||||
/// length
|
||||
case badHandshakeCipher // = 102
|
||||
|
||||
/// The next protocol is missing, unknown, or
|
||||
case badNextProtocol // = 103
|
||||
|
||||
/// unsupported
|
||||
case badPublicKey // = 104
|
||||
|
||||
/// Other errors
|
||||
case internalError // = 200
|
||||
|
||||
init() {
|
||||
self = .badMessage
|
||||
}
|
||||
|
||||
init?(rawValue: Int) {
|
||||
switch rawValue {
|
||||
case 1: self = .badMessage
|
||||
case 2: self = .badMessageType
|
||||
case 3: self = .incorrectMessage
|
||||
case 4: self = .badMessageData
|
||||
case 100: self = .badVersion
|
||||
case 101: self = .badRandom
|
||||
case 102: self = .badHandshakeCipher
|
||||
case 103: self = .badNextProtocol
|
||||
case 104: self = .badPublicKey
|
||||
case 200: self = .internalError
|
||||
default: return nil
|
||||
}
|
||||
}
|
||||
|
||||
var rawValue: Int {
|
||||
switch self {
|
||||
case .badMessage: return 1
|
||||
case .badMessageType: return 2
|
||||
case .incorrectMessage: return 3
|
||||
case .badMessageData: return 4
|
||||
case .badVersion: return 100
|
||||
case .badRandom: return 101
|
||||
case .badHandshakeCipher: return 102
|
||||
case .badNextProtocol: return 103
|
||||
case .badPublicKey: return 104
|
||||
case .internalError: return 200
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _type: Securegcm_Ukey2Alert.AlertType? = nil
|
||||
fileprivate var _errorMessage: String? = nil
|
||||
}
|
||||
|
||||
#if swift(>=4.2)
|
||||
|
||||
extension Securegcm_Ukey2Alert.AlertType: CaseIterable {
|
||||
// Support synthesized by the compiler.
|
||||
}
|
||||
|
||||
#endif // swift(>=4.2)
|
||||
|
||||
struct Securegcm_Ukey2ClientInit {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// highest supported version for rollback
|
||||
var version: Int32 {
|
||||
get {return _version ?? 0}
|
||||
set {_version = newValue}
|
||||
}
|
||||
/// Returns true if `version` has been explicitly set.
|
||||
var hasVersion: Bool {return self._version != nil}
|
||||
/// Clears the value of `version`. Subsequent reads from it will return its default value.
|
||||
mutating func clearVersion() {self._version = nil}
|
||||
|
||||
/// protection
|
||||
var random: Data {
|
||||
get {return _random ?? Data()}
|
||||
set {_random = newValue}
|
||||
}
|
||||
/// Returns true if `random` has been explicitly set.
|
||||
var hasRandom: Bool {return self._random != nil}
|
||||
/// Clears the value of `random`. Subsequent reads from it will return its default value.
|
||||
mutating func clearRandom() {self._random = nil}
|
||||
|
||||
var cipherCommitments: [Securegcm_Ukey2ClientInit.CipherCommitment] = []
|
||||
|
||||
/// Next protocol that the client wants to speak.
|
||||
var nextProtocol: String {
|
||||
get {return _nextProtocol ?? String()}
|
||||
set {_nextProtocol = newValue}
|
||||
}
|
||||
/// Returns true if `nextProtocol` has been explicitly set.
|
||||
var hasNextProtocol: Bool {return self._nextProtocol != nil}
|
||||
/// Clears the value of `nextProtocol`. Subsequent reads from it will return its default value.
|
||||
mutating func clearNextProtocol() {self._nextProtocol = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
/// One commitment (hash of ClientFinished containing public key) per supported
|
||||
/// cipher
|
||||
struct CipherCommitment {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
var handshakeCipher: Securegcm_Ukey2HandshakeCipher {
|
||||
get {return _handshakeCipher ?? .reserved}
|
||||
set {_handshakeCipher = newValue}
|
||||
}
|
||||
/// Returns true if `handshakeCipher` has been explicitly set.
|
||||
var hasHandshakeCipher: Bool {return self._handshakeCipher != nil}
|
||||
/// Clears the value of `handshakeCipher`. Subsequent reads from it will return its default value.
|
||||
mutating func clearHandshakeCipher() {self._handshakeCipher = nil}
|
||||
|
||||
var commitment: Data {
|
||||
get {return _commitment ?? Data()}
|
||||
set {_commitment = newValue}
|
||||
}
|
||||
/// Returns true if `commitment` has been explicitly set.
|
||||
var hasCommitment: Bool {return self._commitment != nil}
|
||||
/// Clears the value of `commitment`. Subsequent reads from it will return its default value.
|
||||
mutating func clearCommitment() {self._commitment = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _handshakeCipher: Securegcm_Ukey2HandshakeCipher? = nil
|
||||
fileprivate var _commitment: Data? = nil
|
||||
}
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _version: Int32? = nil
|
||||
fileprivate var _random: Data? = nil
|
||||
fileprivate var _nextProtocol: String? = nil
|
||||
}
|
||||
|
||||
struct Securegcm_Ukey2ServerInit {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// highest supported version for rollback
|
||||
var version: Int32 {
|
||||
get {return _version ?? 0}
|
||||
set {_version = newValue}
|
||||
}
|
||||
/// Returns true if `version` has been explicitly set.
|
||||
var hasVersion: Bool {return self._version != nil}
|
||||
/// Clears the value of `version`. Subsequent reads from it will return its default value.
|
||||
mutating func clearVersion() {self._version = nil}
|
||||
|
||||
/// protection
|
||||
var random: Data {
|
||||
get {return _random ?? Data()}
|
||||
set {_random = newValue}
|
||||
}
|
||||
/// Returns true if `random` has been explicitly set.
|
||||
var hasRandom: Bool {return self._random != nil}
|
||||
/// Clears the value of `random`. Subsequent reads from it will return its default value.
|
||||
mutating func clearRandom() {self._random = nil}
|
||||
|
||||
/// Selected Cipher and corresponding public key
|
||||
var handshakeCipher: Securegcm_Ukey2HandshakeCipher {
|
||||
get {return _handshakeCipher ?? .reserved}
|
||||
set {_handshakeCipher = newValue}
|
||||
}
|
||||
/// Returns true if `handshakeCipher` has been explicitly set.
|
||||
var hasHandshakeCipher: Bool {return self._handshakeCipher != nil}
|
||||
/// Clears the value of `handshakeCipher`. Subsequent reads from it will return its default value.
|
||||
mutating func clearHandshakeCipher() {self._handshakeCipher = nil}
|
||||
|
||||
var publicKey: Data {
|
||||
get {return _publicKey ?? Data()}
|
||||
set {_publicKey = newValue}
|
||||
}
|
||||
/// Returns true if `publicKey` has been explicitly set.
|
||||
var hasPublicKey: Bool {return self._publicKey != nil}
|
||||
/// Clears the value of `publicKey`. Subsequent reads from it will return its default value.
|
||||
mutating func clearPublicKey() {self._publicKey = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _version: Int32? = nil
|
||||
fileprivate var _random: Data? = nil
|
||||
fileprivate var _handshakeCipher: Securegcm_Ukey2HandshakeCipher? = nil
|
||||
fileprivate var _publicKey: Data? = nil
|
||||
}
|
||||
|
||||
struct Securegcm_Ukey2ClientFinished {
|
||||
// SwiftProtobuf.Message conformance is added in an extension below. See the
|
||||
// `Message` and `Message+*Additions` files in the SwiftProtobuf library for
|
||||
// methods supported on all messages.
|
||||
|
||||
/// public key matching selected handshake
|
||||
var publicKey: Data {
|
||||
get {return _publicKey ?? Data()}
|
||||
set {_publicKey = newValue}
|
||||
}
|
||||
/// Returns true if `publicKey` has been explicitly set.
|
||||
var hasPublicKey: Bool {return self._publicKey != nil}
|
||||
/// Clears the value of `publicKey`. Subsequent reads from it will return its default value.
|
||||
mutating func clearPublicKey() {self._publicKey = nil}
|
||||
|
||||
var unknownFields = SwiftProtobuf.UnknownStorage()
|
||||
|
||||
init() {}
|
||||
|
||||
fileprivate var _publicKey: Data? = nil
|
||||
}
|
||||
|
||||
#if swift(>=5.5) && canImport(_Concurrency)
|
||||
extension Securegcm_Ukey2HandshakeCipher: @unchecked Sendable {}
|
||||
extension Securegcm_Ukey2Message: @unchecked Sendable {}
|
||||
extension Securegcm_Ukey2Message.TypeEnum: @unchecked Sendable {}
|
||||
extension Securegcm_Ukey2Alert: @unchecked Sendable {}
|
||||
extension Securegcm_Ukey2Alert.AlertType: @unchecked Sendable {}
|
||||
extension Securegcm_Ukey2ClientInit: @unchecked Sendable {}
|
||||
extension Securegcm_Ukey2ClientInit.CipherCommitment: @unchecked Sendable {}
|
||||
extension Securegcm_Ukey2ServerInit: @unchecked Sendable {}
|
||||
extension Securegcm_Ukey2ClientFinished: @unchecked Sendable {}
|
||||
#endif // swift(>=5.5) && canImport(_Concurrency)
|
||||
|
||||
// MARK: - Code below here is support for the SwiftProtobuf runtime.
|
||||
|
||||
fileprivate let _protobuf_package = "securegcm"
|
||||
|
||||
extension Securegcm_Ukey2HandshakeCipher: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "RESERVED"),
|
||||
100: .same(proto: "P256_SHA512"),
|
||||
200: .same(proto: "CURVE25519_SHA512"),
|
||||
]
|
||||
}
|
||||
|
||||
extension Securegcm_Ukey2Message: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".Ukey2Message"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "message_type"),
|
||||
2: .standard(proto: "message_data"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularEnumField(value: &self._messageType) }()
|
||||
case 2: try { try decoder.decodeSingularBytesField(value: &self._messageData) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._messageType {
|
||||
try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._messageData {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securegcm_Ukey2Message, rhs: Securegcm_Ukey2Message) -> Bool {
|
||||
if lhs._messageType != rhs._messageType {return false}
|
||||
if lhs._messageData != rhs._messageData {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securegcm_Ukey2Message.TypeEnum: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
0: .same(proto: "UNKNOWN_DO_NOT_USE"),
|
||||
1: .same(proto: "ALERT"),
|
||||
2: .same(proto: "CLIENT_INIT"),
|
||||
3: .same(proto: "SERVER_INIT"),
|
||||
4: .same(proto: "CLIENT_FINISH"),
|
||||
]
|
||||
}
|
||||
|
||||
extension Securegcm_Ukey2Alert: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".Ukey2Alert"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "type"),
|
||||
2: .standard(proto: "error_message"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularEnumField(value: &self._type) }()
|
||||
case 2: try { try decoder.decodeSingularStringField(value: &self._errorMessage) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._type {
|
||||
try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._errorMessage {
|
||||
try visitor.visitSingularStringField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securegcm_Ukey2Alert, rhs: Securegcm_Ukey2Alert) -> Bool {
|
||||
if lhs._type != rhs._type {return false}
|
||||
if lhs._errorMessage != rhs._errorMessage {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securegcm_Ukey2Alert.AlertType: SwiftProtobuf._ProtoNameProviding {
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "BAD_MESSAGE"),
|
||||
2: .same(proto: "BAD_MESSAGE_TYPE"),
|
||||
3: .same(proto: "INCORRECT_MESSAGE"),
|
||||
4: .same(proto: "BAD_MESSAGE_DATA"),
|
||||
100: .same(proto: "BAD_VERSION"),
|
||||
101: .same(proto: "BAD_RANDOM"),
|
||||
102: .same(proto: "BAD_HANDSHAKE_CIPHER"),
|
||||
103: .same(proto: "BAD_NEXT_PROTOCOL"),
|
||||
104: .same(proto: "BAD_PUBLIC_KEY"),
|
||||
200: .same(proto: "INTERNAL_ERROR"),
|
||||
]
|
||||
}
|
||||
|
||||
extension Securegcm_Ukey2ClientInit: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".Ukey2ClientInit"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "version"),
|
||||
2: .same(proto: "random"),
|
||||
3: .standard(proto: "cipher_commitments"),
|
||||
4: .standard(proto: "next_protocol"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularInt32Field(value: &self._version) }()
|
||||
case 2: try { try decoder.decodeSingularBytesField(value: &self._random) }()
|
||||
case 3: try { try decoder.decodeRepeatedMessageField(value: &self.cipherCommitments) }()
|
||||
case 4: try { try decoder.decodeSingularStringField(value: &self._nextProtocol) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._version {
|
||||
try visitor.visitSingularInt32Field(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._random {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
if !self.cipherCommitments.isEmpty {
|
||||
try visitor.visitRepeatedMessageField(value: self.cipherCommitments, fieldNumber: 3)
|
||||
}
|
||||
try { if let v = self._nextProtocol {
|
||||
try visitor.visitSingularStringField(value: v, fieldNumber: 4)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securegcm_Ukey2ClientInit, rhs: Securegcm_Ukey2ClientInit) -> Bool {
|
||||
if lhs._version != rhs._version {return false}
|
||||
if lhs._random != rhs._random {return false}
|
||||
if lhs.cipherCommitments != rhs.cipherCommitments {return false}
|
||||
if lhs._nextProtocol != rhs._nextProtocol {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securegcm_Ukey2ClientInit.CipherCommitment: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = Securegcm_Ukey2ClientInit.protoMessageName + ".CipherCommitment"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "handshake_cipher"),
|
||||
2: .same(proto: "commitment"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularEnumField(value: &self._handshakeCipher) }()
|
||||
case 2: try { try decoder.decodeSingularBytesField(value: &self._commitment) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._handshakeCipher {
|
||||
try visitor.visitSingularEnumField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._commitment {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securegcm_Ukey2ClientInit.CipherCommitment, rhs: Securegcm_Ukey2ClientInit.CipherCommitment) -> Bool {
|
||||
if lhs._handshakeCipher != rhs._handshakeCipher {return false}
|
||||
if lhs._commitment != rhs._commitment {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securegcm_Ukey2ServerInit: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".Ukey2ServerInit"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .same(proto: "version"),
|
||||
2: .same(proto: "random"),
|
||||
3: .standard(proto: "handshake_cipher"),
|
||||
4: .standard(proto: "public_key"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularInt32Field(value: &self._version) }()
|
||||
case 2: try { try decoder.decodeSingularBytesField(value: &self._random) }()
|
||||
case 3: try { try decoder.decodeSingularEnumField(value: &self._handshakeCipher) }()
|
||||
case 4: try { try decoder.decodeSingularBytesField(value: &self._publicKey) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._version {
|
||||
try visitor.visitSingularInt32Field(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try { if let v = self._random {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 2)
|
||||
} }()
|
||||
try { if let v = self._handshakeCipher {
|
||||
try visitor.visitSingularEnumField(value: v, fieldNumber: 3)
|
||||
} }()
|
||||
try { if let v = self._publicKey {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 4)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securegcm_Ukey2ServerInit, rhs: Securegcm_Ukey2ServerInit) -> Bool {
|
||||
if lhs._version != rhs._version {return false}
|
||||
if lhs._random != rhs._random {return false}
|
||||
if lhs._handshakeCipher != rhs._handshakeCipher {return false}
|
||||
if lhs._publicKey != rhs._publicKey {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
extension Securegcm_Ukey2ClientFinished: SwiftProtobuf.Message, SwiftProtobuf._MessageImplementationBase, SwiftProtobuf._ProtoNameProviding {
|
||||
static let protoMessageName: String = _protobuf_package + ".Ukey2ClientFinished"
|
||||
static let _protobuf_nameMap: SwiftProtobuf._NameMap = [
|
||||
1: .standard(proto: "public_key"),
|
||||
]
|
||||
|
||||
mutating func decodeMessage<D: SwiftProtobuf.Decoder>(decoder: inout D) throws {
|
||||
while let fieldNumber = try decoder.nextFieldNumber() {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every case branch when no optimizations are
|
||||
// enabled. https://github.com/apple/swift-protobuf/issues/1034
|
||||
switch fieldNumber {
|
||||
case 1: try { try decoder.decodeSingularBytesField(value: &self._publicKey) }()
|
||||
default: break
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func traverse<V: SwiftProtobuf.Visitor>(visitor: inout V) throws {
|
||||
// The use of inline closures is to circumvent an issue where the compiler
|
||||
// allocates stack space for every if/case branch local when no optimizations
|
||||
// are enabled. https://github.com/apple/swift-protobuf/issues/1034 and
|
||||
// https://github.com/apple/swift-protobuf/issues/1182
|
||||
try { if let v = self._publicKey {
|
||||
try visitor.visitSingularBytesField(value: v, fieldNumber: 1)
|
||||
} }()
|
||||
try unknownFields.traverse(visitor: &visitor)
|
||||
}
|
||||
|
||||
static func ==(lhs: Securegcm_Ukey2ClientFinished, rhs: Securegcm_Ukey2ClientFinished) -> Bool {
|
||||
if lhs._publicKey != rhs._publicKey {return false}
|
||||
if lhs.unknownFields != rhs.unknownFields {return false}
|
||||
return true
|
||||
}
|
||||
}
|
||||
1617
NearbyShare/Protobuf/wire_format.pb.swift
Normal file
1617
NearbyShare/Protobuf/wire_format.pb.swift
Normal file
File diff suppressed because it is too large
Load Diff
81
NearbyShare/ProtobufSource/device_to_device_messages.proto
Normal file
81
NearbyShare/ProtobufSource/device_to_device_messages.proto
Normal file
@@ -0,0 +1,81 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package securegcm;
|
||||
|
||||
import "securemessage.proto";
|
||||
|
||||
option optimize_for = LITE_RUNTIME;
|
||||
option java_package = "com.google.security.cryptauth.lib.securegcm";
|
||||
option java_outer_classname = "DeviceToDeviceMessagesProto";
|
||||
option objc_class_prefix = "SGCM";
|
||||
|
||||
// Used by protocols between devices
|
||||
message DeviceToDeviceMessage {
|
||||
// the payload of the message
|
||||
optional bytes message = 1;
|
||||
|
||||
// the sequence number of the message - must be increasing.
|
||||
optional int32 sequence_number = 2;
|
||||
}
|
||||
|
||||
// sent as the first message from initiator to responder
|
||||
// in an unauthenticated Diffie-Hellman Key Exchange
|
||||
message InitiatorHello {
|
||||
// The session public key to send to the responder
|
||||
optional securemessage.GenericPublicKey public_dh_key = 1;
|
||||
|
||||
// The protocol version
|
||||
optional int32 protocol_version = 2 [default = 0];
|
||||
}
|
||||
|
||||
// sent inside the header of the first message from the responder to the
|
||||
// initiator in an unauthenticated Diffie-Hellman Key Exchange
|
||||
message ResponderHello {
|
||||
// The session public key to send to the initiator
|
||||
optional securemessage.GenericPublicKey public_dh_key = 1;
|
||||
|
||||
// The protocol version
|
||||
optional int32 protocol_version = 2 [default = 0];
|
||||
}
|
||||
|
||||
// Type of curve
|
||||
enum Curve { ED_25519 = 1; }
|
||||
|
||||
// A convenience proto for encoding curve points in affine representation
|
||||
message EcPoint {
|
||||
required Curve curve = 1;
|
||||
|
||||
// x and y are encoded in big-endian two's complement
|
||||
// client MUST verify (x,y) is a valid point on the specified curve
|
||||
required bytes x = 2;
|
||||
required bytes y = 3;
|
||||
}
|
||||
|
||||
message SpakeHandshakeMessage {
|
||||
// Each flow in the protocol bumps this counter
|
||||
optional int32 flow_number = 1;
|
||||
|
||||
// Some (but not all) SPAKE flows send a point on an elliptic curve
|
||||
optional EcPoint ec_point = 2;
|
||||
|
||||
// Some (but not all) SPAKE flows send a hash value
|
||||
optional bytes hash_value = 3;
|
||||
|
||||
// The last flow of a SPAKE protocol can send an optional payload,
|
||||
// since the key exchange is already complete on the sender's side.
|
||||
optional bytes payload = 4;
|
||||
}
|
||||
403
NearbyShare/ProtobufSource/offline_wire_formats.proto
Normal file
403
NearbyShare/ProtobufSource/offline_wire_formats.proto
Normal file
@@ -0,0 +1,403 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package location.nearby.connections;
|
||||
|
||||
option optimize_for = LITE_RUNTIME;
|
||||
option java_outer_classname = "OfflineWireFormatsProto";
|
||||
option java_package = "com.google.location.nearby.connections.proto";
|
||||
option objc_class_prefix = "GNCP";
|
||||
|
||||
message OfflineFrame {
|
||||
enum Version {
|
||||
UNKNOWN_VERSION = 0;
|
||||
V1 = 1;
|
||||
}
|
||||
optional Version version = 1;
|
||||
|
||||
// Right now there's only 1 version, but if there are more, exactly one of
|
||||
// the following fields will be set.
|
||||
optional V1Frame v1 = 2;
|
||||
}
|
||||
|
||||
message V1Frame {
|
||||
enum FrameType {
|
||||
UNKNOWN_FRAME_TYPE = 0;
|
||||
CONNECTION_REQUEST = 1;
|
||||
CONNECTION_RESPONSE = 2;
|
||||
PAYLOAD_TRANSFER = 3;
|
||||
BANDWIDTH_UPGRADE_NEGOTIATION = 4;
|
||||
KEEP_ALIVE = 5;
|
||||
DISCONNECTION = 6;
|
||||
PAIRED_KEY_ENCRYPTION = 7;
|
||||
}
|
||||
optional FrameType type = 1;
|
||||
|
||||
// Exactly one of the following fields will be set.
|
||||
optional ConnectionRequestFrame connection_request = 2;
|
||||
optional ConnectionResponseFrame connection_response = 3;
|
||||
optional PayloadTransferFrame payload_transfer = 4;
|
||||
optional BandwidthUpgradeNegotiationFrame bandwidth_upgrade_negotiation = 5;
|
||||
optional KeepAliveFrame keep_alive = 6;
|
||||
optional DisconnectionFrame disconnection = 7;
|
||||
optional PairedKeyEncryptionFrame paired_key_encryption = 8;
|
||||
}
|
||||
|
||||
message ConnectionRequestFrame {
|
||||
// Should always match cs/symbol:location.nearby.proto.connections.Medium
|
||||
// LINT.IfChange
|
||||
enum Medium {
|
||||
UNKNOWN_MEDIUM = 0;
|
||||
MDNS = 1 [deprecated = true];
|
||||
BLUETOOTH = 2;
|
||||
WIFI_HOTSPOT = 3;
|
||||
BLE = 4;
|
||||
WIFI_LAN = 5;
|
||||
WIFI_AWARE = 6;
|
||||
NFC = 7;
|
||||
WIFI_DIRECT = 8;
|
||||
WEB_RTC = 9;
|
||||
BLE_L2CAP = 10;
|
||||
USB = 11;
|
||||
}
|
||||
// LINT.ThenChange(//depot/google3/third_party/nearby/proto/connections_enums.proto)
|
||||
|
||||
optional string endpoint_id = 1;
|
||||
optional string endpoint_name = 2;
|
||||
optional bytes handshake_data = 3;
|
||||
// A random number generated for each outgoing connection that is presently
|
||||
// used to act as a tiebreaker when 2 devices connect to each other
|
||||
// simultaneously; this can also be used for other initialization-scoped
|
||||
// things in the future.
|
||||
optional int32 nonce = 4;
|
||||
// The mediums this device supports upgrading to. This list should be filtered
|
||||
// by both the strategy and this device's individual limitations.
|
||||
repeated Medium mediums = 5;
|
||||
optional bytes endpoint_info = 6;
|
||||
optional MediumMetadata medium_metadata = 7;
|
||||
optional int32 keep_alive_interval_millis = 8;
|
||||
optional int32 keep_alive_timeout_millis = 9;
|
||||
// The type of {@link Device} object.
|
||||
optional int32 device_type = 10 [default = 0];
|
||||
// The bytes of serialized {@link Device} object.
|
||||
optional bytes device_info = 11;
|
||||
}
|
||||
|
||||
message ConnectionResponseFrame {
|
||||
// This doesn't need to send back endpoint_id and endpoint_name (like
|
||||
// the ConnectionRequestFrame does) because those have already been
|
||||
// transmitted out-of-band, at the time this endpoint was discovered.
|
||||
|
||||
// One of:
|
||||
//
|
||||
// - ConnectionsStatusCodes.STATUS_OK
|
||||
// - ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED.
|
||||
optional int32 status = 1 [deprecated = true];
|
||||
optional bytes handshake_data = 2;
|
||||
|
||||
// Used to replace the status integer parameter with a meaningful enum item.
|
||||
// Map ConnectionsStatusCodes.STATUS_OK to ACCEPT and
|
||||
// ConnectionsStatusCodes.STATUS_CONNECTION_REJECTED to REJECT.
|
||||
// Flag: connection_replace_status_with_response_connectionResponseFrame
|
||||
enum ResponseStatus {
|
||||
UNKNOWN_RESPONSE_STATUS = 0;
|
||||
ACCEPT = 1;
|
||||
REJECT = 2;
|
||||
}
|
||||
optional ResponseStatus response = 3;
|
||||
optional OsInfo os_info = 4;
|
||||
// A bitmask value to indicate which medium supports Multiplex transmission
|
||||
// feature. Each supporting medium could utilize one bit starting from the
|
||||
// least significant bit in this field. eq. BT utilizes the LSB bit which 0x01
|
||||
// means bt supports multiplex while 0x00 means not. Refer to ClientProxy.java
|
||||
// for the bit usages.
|
||||
optional int32 multiplex_socket_bitmask = 5;
|
||||
optional int32 nearby_connections_version = 6;
|
||||
}
|
||||
|
||||
message PayloadTransferFrame {
|
||||
enum PacketType {
|
||||
UNKNOWN_PACKET_TYPE = 0;
|
||||
DATA = 1;
|
||||
CONTROL = 2;
|
||||
}
|
||||
|
||||
message PayloadHeader {
|
||||
enum PayloadType {
|
||||
UNKNOWN_PAYLOAD_TYPE = 0;
|
||||
BYTES = 1;
|
||||
FILE = 2;
|
||||
STREAM = 3;
|
||||
}
|
||||
optional int64 id = 1;
|
||||
optional PayloadType type = 2;
|
||||
optional int64 total_size = 3;
|
||||
optional bool is_sensitive = 4;
|
||||
optional string file_name = 5;
|
||||
optional string parent_folder = 6;
|
||||
}
|
||||
|
||||
// Accompanies DATA packets.
|
||||
message PayloadChunk {
|
||||
enum Flags {
|
||||
LAST_CHUNK = 0x1;
|
||||
}
|
||||
optional int32 flags = 1;
|
||||
optional int64 offset = 2;
|
||||
optional bytes body = 3;
|
||||
}
|
||||
|
||||
// Accompanies CONTROL packets.
|
||||
message ControlMessage {
|
||||
enum EventType {
|
||||
UNKNOWN_EVENT_TYPE = 0;
|
||||
PAYLOAD_ERROR = 1;
|
||||
PAYLOAD_CANCELED = 2;
|
||||
PAYLOAD_RECEIVED_ACK = 3;
|
||||
}
|
||||
|
||||
optional EventType event = 1;
|
||||
optional int64 offset = 2;
|
||||
}
|
||||
|
||||
optional PacketType packet_type = 1;
|
||||
optional PayloadHeader payload_header = 2;
|
||||
|
||||
// Exactly one of the following fields will be set, depending on the type.
|
||||
optional PayloadChunk payload_chunk = 3;
|
||||
optional ControlMessage control_message = 4;
|
||||
}
|
||||
|
||||
message BandwidthUpgradeNegotiationFrame {
|
||||
enum EventType {
|
||||
UNKNOWN_EVENT_TYPE = 0;
|
||||
UPGRADE_PATH_AVAILABLE = 1;
|
||||
LAST_WRITE_TO_PRIOR_CHANNEL = 2;
|
||||
SAFE_TO_CLOSE_PRIOR_CHANNEL = 3;
|
||||
CLIENT_INTRODUCTION = 4;
|
||||
UPGRADE_FAILURE = 5;
|
||||
CLIENT_INTRODUCTION_ACK = 6;
|
||||
}
|
||||
|
||||
// Accompanies UPGRADE_PATH_AVAILABLE and UPGRADE_FAILURE events.
|
||||
message UpgradePathInfo {
|
||||
// Should always match cs/symbol:location.nearby.proto.connections.Medium
|
||||
enum Medium {
|
||||
UNKNOWN_MEDIUM = 0;
|
||||
MDNS = 1 [deprecated = true];
|
||||
BLUETOOTH = 2;
|
||||
WIFI_HOTSPOT = 3;
|
||||
BLE = 4;
|
||||
WIFI_LAN = 5;
|
||||
WIFI_AWARE = 6;
|
||||
NFC = 7;
|
||||
WIFI_DIRECT = 8;
|
||||
WEB_RTC = 9;
|
||||
// 10 is reserved.
|
||||
USB = 11;
|
||||
}
|
||||
|
||||
// Accompanies Medium.WIFI_HOTSPOT.
|
||||
message WifiHotspotCredentials {
|
||||
optional string ssid = 1;
|
||||
optional string password = 2;
|
||||
optional int32 port = 3;
|
||||
optional string gateway = 4 [default = "0.0.0.0"];
|
||||
// This field can be a band or frequency
|
||||
optional int32 frequency = 5 [default = -1];
|
||||
}
|
||||
|
||||
// Accompanies Medium.WIFI_LAN.
|
||||
message WifiLanSocket {
|
||||
optional bytes ip_address = 1;
|
||||
optional int32 wifi_port = 2;
|
||||
}
|
||||
|
||||
// Accompanies Medium.BLUETOOTH.
|
||||
message BluetoothCredentials {
|
||||
optional string service_name = 1;
|
||||
optional string mac_address = 2;
|
||||
}
|
||||
|
||||
// Accompanies Medium.WIFI_AWARE.
|
||||
message WifiAwareCredentials {
|
||||
optional string service_id = 1;
|
||||
optional bytes service_info = 2;
|
||||
optional string password = 3;
|
||||
}
|
||||
|
||||
// Accompanies Medium.WIFI_DIRECT.
|
||||
message WifiDirectCredentials {
|
||||
optional string ssid = 1;
|
||||
optional string password = 2;
|
||||
optional int32 port = 3;
|
||||
optional int32 frequency = 4;
|
||||
optional string gateway = 5 [default = "0.0.0.0"];
|
||||
}
|
||||
|
||||
// Accompanies Medium.WEB_RTC
|
||||
message WebRtcCredentials {
|
||||
optional string peer_id = 1;
|
||||
optional LocationHint location_hint = 2;
|
||||
}
|
||||
|
||||
optional Medium medium = 1;
|
||||
|
||||
// Exactly one of the following fields will be set.
|
||||
optional WifiHotspotCredentials wifi_hotspot_credentials = 2;
|
||||
optional WifiLanSocket wifi_lan_socket = 3;
|
||||
optional BluetoothCredentials bluetooth_credentials = 4;
|
||||
optional WifiAwareCredentials wifi_aware_credentials = 5;
|
||||
optional WifiDirectCredentials wifi_direct_credentials = 6;
|
||||
optional WebRtcCredentials web_rtc_credentials = 8;
|
||||
|
||||
// Disable Encryption for this upgrade medium to improve throughput.
|
||||
optional bool supports_disabling_encryption = 7;
|
||||
|
||||
// An ack will be sent after the CLIENT_INTRODUCTION frame.
|
||||
optional bool supports_client_introduction_ack = 9;
|
||||
}
|
||||
|
||||
// Accompanies CLIENT_INTRODUCTION events.
|
||||
message ClientIntroduction {
|
||||
optional string endpoint_id = 1;
|
||||
optional bool supports_disabling_encryption = 2;
|
||||
}
|
||||
|
||||
// Accompanies CLIENT_INTRODUCTION_ACK events.
|
||||
message ClientIntroductionAck {}
|
||||
|
||||
optional EventType event_type = 1;
|
||||
|
||||
// Exactly one of the following fields will be set.
|
||||
optional UpgradePathInfo upgrade_path_info = 2;
|
||||
optional ClientIntroduction client_introduction = 3;
|
||||
optional ClientIntroductionAck client_introduction_ack = 4;
|
||||
}
|
||||
|
||||
message KeepAliveFrame {
|
||||
// And ack will be sent after receiving KEEP_ALIVE frame.
|
||||
optional bool ack = 1;
|
||||
}
|
||||
|
||||
// Informs the remote side to immediately severe the socket connection.
|
||||
// Used in bandwidth upgrades to get around a race condition, but may be used
|
||||
// in other situations to trigger a faster disconnection event than waiting for
|
||||
// socket closed on the remote side.
|
||||
message DisconnectionFrame {
|
||||
// Apply safe-to-disconnect protocol if true.
|
||||
optional bool request_safe_to_disconnect = 1;
|
||||
|
||||
// Ack of receiving Disconnection frame will be sent to the sender
|
||||
// frame.
|
||||
optional bool ack_safe_to_disconnect = 2;
|
||||
}
|
||||
|
||||
// A paired key encryption packet sent between devices, contains signed data.
|
||||
message PairedKeyEncryptionFrame {
|
||||
// The encrypted data (raw authentication token for the established
|
||||
// connection) in byte array format.
|
||||
optional bytes signed_data = 1;
|
||||
}
|
||||
|
||||
message MediumMetadata {
|
||||
// True if local device supports 5GHz.
|
||||
optional bool supports_5_ghz = 1;
|
||||
// WiFi LAN BSSID, in the form of a six-byte MAC address: XX:XX:XX:XX:XX:XX
|
||||
optional string bssid = 2;
|
||||
// IP address, in network byte order: the highest order byte of the address is
|
||||
// in byte[0].
|
||||
optional bytes ip_address = 3;
|
||||
// True if local device supports 6GHz.
|
||||
optional bool supports_6_ghz = 4;
|
||||
// True if local device has mobile radio.
|
||||
optional bool mobile_radio = 5;
|
||||
// The frequency of the WiFi LAN AP(in MHz). Or -1 is not associated with an
|
||||
// AP over WiFi, -2 represents the active network uses an Ethernet transport.
|
||||
optional int32 ap_frequency = 6 [default = -1];
|
||||
// Available channels on the local device.
|
||||
optional AvailableChannels available_channels = 7;
|
||||
// Usable WiFi Direct client channels on the local device.
|
||||
optional WifiDirectCliUsableChannels wifi_direct_cli_usable_channels = 8;
|
||||
// Usable WiFi LAN channels on the local device.
|
||||
optional WifiLanUsableChannels wifi_lan_usable_channels = 9;
|
||||
// Usable WiFi Aware channels on the local device.
|
||||
optional WifiAwareUsableChannels wifi_aware_usable_channels = 10;
|
||||
// Usable WiFi Hotspot STA channels on the local device.
|
||||
optional WifiHotspotStaUsableChannels wifi_hotspot_sta_usable_channels = 11;
|
||||
}
|
||||
|
||||
// Available channels on the local device.
|
||||
message AvailableChannels {
|
||||
repeated int32 channels = 1 [packed = true];
|
||||
}
|
||||
|
||||
// Usable WiFi Direct client channels on the local device.
|
||||
message WifiDirectCliUsableChannels {
|
||||
repeated int32 channels = 1 [packed = true];
|
||||
}
|
||||
|
||||
// Usable WiFi LAN channels on the local device.
|
||||
message WifiLanUsableChannels {
|
||||
repeated int32 channels = 1 [packed = true];
|
||||
}
|
||||
|
||||
// Usable WiFi Aware channels on the local device.
|
||||
message WifiAwareUsableChannels {
|
||||
repeated int32 channels = 1 [packed = true];
|
||||
}
|
||||
|
||||
// Usable WiFi Hotspot STA channels on the local device.
|
||||
message WifiHotspotStaUsableChannels {
|
||||
repeated int32 channels = 1 [packed = true];
|
||||
}
|
||||
|
||||
// LocationHint is used to specify a location as well as format.
|
||||
message LocationHint {
|
||||
// Location is the location, provided in the format specified by format.
|
||||
optional string location = 1;
|
||||
|
||||
// the format of location.
|
||||
optional LocationStandard.Format format = 2;
|
||||
}
|
||||
|
||||
message LocationStandard {
|
||||
enum Format {
|
||||
UNKNOWN = 0;
|
||||
// E164 country codes:
|
||||
// https://en.wikipedia.org/wiki/List_of_country_calling_codes
|
||||
// e.g. +1 for USA
|
||||
E164_CALLING = 1;
|
||||
|
||||
// ISO 3166-1 alpha-2 country codes:
|
||||
// https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
|
||||
ISO_3166_1_ALPHA_2 = 2;
|
||||
}
|
||||
}
|
||||
|
||||
// Device capability for OS information.
|
||||
message OsInfo {
|
||||
enum OsType {
|
||||
UNKNOWN_OS_TYPE = 0;
|
||||
ANDROID = 1;
|
||||
CHROME_OS = 2;
|
||||
WINDOWS = 3;
|
||||
APPLE = 4;
|
||||
LINUX = 100; // g3 test environment
|
||||
}
|
||||
|
||||
optional OsType type = 1;
|
||||
}
|
||||
308
NearbyShare/ProtobufSource/securegcm.proto
Normal file
308
NearbyShare/ProtobufSource/securegcm.proto
Normal file
@@ -0,0 +1,308 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package securegcm;
|
||||
|
||||
option optimize_for = LITE_RUNTIME;
|
||||
option java_package = "com.google.security.cryptauth.lib.securegcm";
|
||||
option java_outer_classname = "SecureGcmProto";
|
||||
option objc_class_prefix = "SGCM";
|
||||
|
||||
// Message used only during enrollment
|
||||
// Field numbers should be kept in sync with DeviceInfo in:
|
||||
// java/com/google/security/cryptauth/backend/services/common/common.proto
|
||||
message GcmDeviceInfo {
|
||||
// This field's name does not match the one in DeviceInfo for legacy reasons.
|
||||
// Consider using long_device_id and device_type instead when enrolling
|
||||
// non-android devices.
|
||||
optional fixed64 android_device_id = 1;
|
||||
|
||||
// Used for device_address of DeviceInfo field 2, but for GCM capable devices.
|
||||
optional bytes gcm_registration_id = 102;
|
||||
|
||||
// Used for device_address of DeviceInfo field 2, but for iOS devices.
|
||||
optional bytes apn_registration_id = 202;
|
||||
|
||||
// Does the user have notifications enabled for the given device address.
|
||||
optional bool notification_enabled = 203 [default = true];
|
||||
|
||||
// Used for device_address of DeviceInfo field 2, a Bluetooth Mac address for
|
||||
// the device (e.g., to be used with EasyUnlock)
|
||||
optional string bluetooth_mac_address = 302;
|
||||
|
||||
// SHA-256 hash of the device master key (from the key exchange).
|
||||
// Differs from DeviceInfo field 3, which contains the actual master key.
|
||||
optional bytes device_master_key_hash = 103;
|
||||
|
||||
// A SecureMessage.EcP256PublicKey
|
||||
required bytes user_public_key = 4;
|
||||
|
||||
// device's model name
|
||||
// (e.g., an android.os.Build.MODEL or UIDevice.model)
|
||||
optional string device_model = 7;
|
||||
|
||||
// device's locale
|
||||
optional string locale = 8;
|
||||
|
||||
// The handle for user_public_key (and implicitly, a master key)
|
||||
optional bytes key_handle = 9;
|
||||
|
||||
// The initial counter value for the device, sent by the device
|
||||
optional int64 counter = 12 [default = 0];
|
||||
|
||||
// The Operating System version on the device
|
||||
// (e.g., an android.os.Build.DISPLAY or UIDevice.systemVersion)
|
||||
optional string device_os_version = 13;
|
||||
|
||||
// The Operating System version number on the device
|
||||
// (e.g., an android.os.Build.VERSION.SDK_INT)
|
||||
optional int64 device_os_version_code = 14;
|
||||
|
||||
// The Operating System release on the device
|
||||
// (e.g., an android.os.Build.VERSION.RELEASE)
|
||||
optional string device_os_release = 15;
|
||||
|
||||
// The Operating System codename on the device
|
||||
// (e.g., an android.os.Build.VERSION.CODENAME or UIDevice.systemName)
|
||||
optional string device_os_codename = 16;
|
||||
|
||||
// The software version running on the device
|
||||
// (e.g., Authenticator app version string)
|
||||
optional string device_software_version = 17;
|
||||
|
||||
// The software version number running on the device
|
||||
// (e.g., Authenticator app version code)
|
||||
optional int64 device_software_version_code = 18;
|
||||
|
||||
// Software package information if applicable
|
||||
// (e.g., com.google.android.apps.authenticator2)
|
||||
optional string device_software_package = 19;
|
||||
|
||||
// Size of the display in thousandths of an inch (e.g., 7000 mils = 7 in)
|
||||
optional int32 device_display_diagonal_mils = 22;
|
||||
|
||||
// For Authzen capable devices, their Authzen protocol version
|
||||
optional int32 device_authzen_version = 24;
|
||||
|
||||
// Not all devices have device identifiers that fit in 64 bits.
|
||||
optional bytes long_device_id = 29;
|
||||
|
||||
// The device manufacturer name
|
||||
// (e.g., android.os.Build.MANUFACTURER)
|
||||
optional string device_manufacturer = 31;
|
||||
|
||||
// Used to indicate which type of device this is.
|
||||
optional DeviceType device_type = 32 [default = ANDROID];
|
||||
|
||||
// Fields corresponding to screenlock type/features and hardware features
|
||||
// should be numbered in the 400 range.
|
||||
|
||||
// Is this device using a secure screenlock (e.g., pattern or pin unlock)
|
||||
optional bool using_secure_screenlock = 400 [default = false];
|
||||
|
||||
// Is auto-unlocking the screenlock (e.g., when at "home") supported?
|
||||
optional bool auto_unlock_screenlock_supported = 401 [default = false];
|
||||
|
||||
// Is auto-unlocking the screenlock (e.g., when at "home") enabled?
|
||||
optional bool auto_unlock_screenlock_enabled = 402 [default = false];
|
||||
|
||||
// Does the device have a Bluetooth (classic) radio?
|
||||
optional bool bluetooth_radio_supported = 403 [default = false];
|
||||
|
||||
// Is the Bluetooth (classic) radio on?
|
||||
optional bool bluetooth_radio_enabled = 404 [default = false];
|
||||
|
||||
// Does the device hardware support a mobile data connection?
|
||||
optional bool mobile_data_supported = 405 [default = false];
|
||||
|
||||
// Does the device support tethering?
|
||||
optional bool tethering_supported = 406 [default = false];
|
||||
|
||||
// Does the device have a BLE radio?
|
||||
optional bool ble_radio_supported = 407 [default = false];
|
||||
|
||||
// Is the device a "Pixel Experience" Android device?
|
||||
optional bool pixel_experience = 408 [default = false];
|
||||
|
||||
// Is the device running in the ARC++ container on a chromebook?
|
||||
optional bool arc_plus_plus = 409 [default = false];
|
||||
|
||||
// Is the value set in |using_secure_screenlock| reliable? On some Android
|
||||
// devices, the platform API to get the screenlock state is not trustworthy.
|
||||
// See b/32212161.
|
||||
optional bool is_screenlock_state_flaky = 410 [default = false];
|
||||
|
||||
// A list of multi-device software features supported by the device.
|
||||
repeated SoftwareFeature supported_software_features = 411;
|
||||
|
||||
// A list of multi-device software features currently enabled (active) on the
|
||||
// device.
|
||||
repeated SoftwareFeature enabled_software_features = 412;
|
||||
|
||||
// The enrollment session id this is sent with
|
||||
optional bytes enrollment_session_id = 1000;
|
||||
|
||||
// A copy of the user's OAuth token
|
||||
optional string oauth_token = 1001;
|
||||
}
|
||||
|
||||
// This enum is used by iOS devices as values for device_display_diagonal_mils
|
||||
// in GcmDeviceInfo. There is no good way to calculate it on those devices.
|
||||
enum AppleDeviceDiagonalMils {
|
||||
// This is the mils diagonal on an iPhone 5.
|
||||
APPLE_PHONE = 4000;
|
||||
// This is the mils diagonal on an iPad mini.
|
||||
APPLE_PAD = 7900;
|
||||
}
|
||||
|
||||
// This should be kept in sync with DeviceType in:
|
||||
// java/com/google/security/cryptauth/backend/services/common/common_enums.proto
|
||||
enum DeviceType {
|
||||
UNKNOWN = 0;
|
||||
ANDROID = 1;
|
||||
CHROME = 2;
|
||||
IOS = 3;
|
||||
BROWSER = 4;
|
||||
OSX = 5;
|
||||
}
|
||||
|
||||
// MultiDevice features which may be supported and enabled on a device. See
|
||||
enum SoftwareFeature {
|
||||
UNKNOWN_FEATURE = 0;
|
||||
BETTER_TOGETHER_HOST = 1;
|
||||
BETTER_TOGETHER_CLIENT = 2;
|
||||
EASY_UNLOCK_HOST = 3;
|
||||
EASY_UNLOCK_CLIENT = 4;
|
||||
MAGIC_TETHER_HOST = 5;
|
||||
MAGIC_TETHER_CLIENT = 6;
|
||||
SMS_CONNECT_HOST = 7;
|
||||
SMS_CONNECT_CLIENT = 8;
|
||||
}
|
||||
|
||||
// A list of "reasons" that can be provided for calling server-side APIs.
|
||||
// This is particularly important for calls that can be triggered by different
|
||||
// kinds of events. Please try to keep reasons as generic as possible, so that
|
||||
// codes can be re-used by various callers in a sensible fashion.
|
||||
enum InvocationReason {
|
||||
REASON_UNKNOWN = 0;
|
||||
// First run of the software package invoking this call
|
||||
REASON_INITIALIZATION = 1;
|
||||
// Ordinary periodic actions (e.g. monthly master key rotation)
|
||||
REASON_PERIODIC = 2;
|
||||
// Slow-cycle periodic action (e.g. yearly keypair rotation???)
|
||||
REASON_SLOW_PERIODIC = 3;
|
||||
// Fast-cycle periodic action (e.g. daily sync for Smart Lock users)
|
||||
REASON_FAST_PERIODIC = 4;
|
||||
// Expired state (e.g. expired credentials, or cached entries) was detected
|
||||
REASON_EXPIRATION = 5;
|
||||
// An unexpected protocol failure occurred (so attempting to repair state)
|
||||
REASON_FAILURE_RECOVERY = 6;
|
||||
// A new account has been added to the device
|
||||
REASON_NEW_ACCOUNT = 7;
|
||||
// An existing account on the device has been changed
|
||||
REASON_CHANGED_ACCOUNT = 8;
|
||||
// The user toggled the state of a feature (e.g. Smart Lock enabled via BT)
|
||||
REASON_FEATURE_TOGGLED = 9;
|
||||
// A "push" from the server caused this action (e.g. a sync tickle)
|
||||
REASON_SERVER_INITIATED = 10;
|
||||
// A local address change triggered this (e.g. GCM registration id changed)
|
||||
REASON_ADDRESS_CHANGE = 11;
|
||||
// A software update has triggered this
|
||||
REASON_SOFTWARE_UPDATE = 12;
|
||||
// A manual action by the user triggered this (e.g. commands sent via adb)
|
||||
REASON_MANUAL = 13;
|
||||
// A custom key has been invalidated on the device (e.g. screen lock is
|
||||
// disabled).
|
||||
REASON_CUSTOM_KEY_INVALIDATION = 14;
|
||||
// Periodic action triggered by auth_proximity
|
||||
REASON_PROXIMITY_PERIODIC = 15;
|
||||
}
|
||||
|
||||
enum Type {
|
||||
ENROLLMENT = 0;
|
||||
TICKLE = 1;
|
||||
TX_REQUEST = 2;
|
||||
TX_REPLY = 3;
|
||||
TX_SYNC_REQUEST = 4;
|
||||
TX_SYNC_RESPONSE = 5;
|
||||
TX_PING = 6;
|
||||
DEVICE_INFO_UPDATE = 7;
|
||||
TX_CANCEL_REQUEST = 8;
|
||||
|
||||
// DEPRECATED (can be re-used after Aug 2015)
|
||||
PROXIMITYAUTH_PAIRING = 10;
|
||||
|
||||
// The kind of identity assertion generated by a "GCM V1" device (i.e.,
|
||||
// an Android phone that has registered with us a public and a symmetric
|
||||
// key)
|
||||
GCMV1_IDENTITY_ASSERTION = 11;
|
||||
|
||||
// Device-to-device communications are protected by an unauthenticated
|
||||
// Diffie-Hellman exchange. The InitiatorHello message is simply the
|
||||
// initiator's public DH key, and is not encoded as a SecureMessage, so
|
||||
// it doesn't have a tag.
|
||||
// The ResponderHello message (which is sent by the responder
|
||||
// to the initiator), on the other hand, carries a payload that is protected
|
||||
// by the derived shared key. It also contains the responder's
|
||||
// public DH key. ResponderHelloAndPayload messages have the
|
||||
// DEVICE_TO_DEVICE_RESPONDER_HELLO tag.
|
||||
DEVICE_TO_DEVICE_RESPONDER_HELLO_PAYLOAD = 12;
|
||||
|
||||
// Device-to-device communications are protected by an unauthenticated
|
||||
// Diffie-Hellman exchange. Once the initiator and responder
|
||||
// agree on a shared key (through Diffie-Hellman), they will use messages
|
||||
// tagged with DEVICE_TO_DEVICE_MESSAGE to exchange data.
|
||||
DEVICE_TO_DEVICE_MESSAGE = 13;
|
||||
|
||||
// Notification to let a device know it should contact a nearby device.
|
||||
DEVICE_PROXIMITY_CALLBACK = 14;
|
||||
|
||||
// Device-to-device communications are protected by an unauthenticated
|
||||
// Diffie-Hellman exchange. During device-to-device authentication, the first
|
||||
// message from initiator (the challenge) is signed and put into the payload
|
||||
// of the message sent back to the initiator.
|
||||
UNLOCK_KEY_SIGNED_CHALLENGE = 15;
|
||||
|
||||
// Specialty (corp only) features
|
||||
LOGIN_NOTIFICATION = 101;
|
||||
}
|
||||
|
||||
message GcmMetadata {
|
||||
required Type type = 1;
|
||||
optional int32 version = 2 [default = 0];
|
||||
}
|
||||
|
||||
message Tickle {
|
||||
// Time after which this tickle should expire
|
||||
optional fixed64 expiry_time = 1;
|
||||
}
|
||||
|
||||
message LoginNotificationInfo {
|
||||
// Time at which the server received the login notification request.
|
||||
optional fixed64 creation_time = 2;
|
||||
|
||||
// Must correspond to user_id in LoginNotificationRequest, if set.
|
||||
optional string email = 3;
|
||||
|
||||
// Host where the user's credentials were used to login, if meaningful.
|
||||
optional string host = 4;
|
||||
|
||||
// Location from where the user's credentials were used, if meaningful.
|
||||
optional string source = 5;
|
||||
|
||||
// Type of login, e.g. ssh, gnome-screensaver, or web.
|
||||
optional string event_type = 6;
|
||||
}
|
||||
126
NearbyShare/ProtobufSource/securemessage.proto
Normal file
126
NearbyShare/ProtobufSource/securemessage.proto
Normal file
@@ -0,0 +1,126 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
// Proto definitions for SecureMessage format
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package securemessage;
|
||||
|
||||
option optimize_for = LITE_RUNTIME;
|
||||
option java_package = "com.google.security.cryptauth.lib.securemessage";
|
||||
option java_outer_classname = "SecureMessageProto";
|
||||
option objc_class_prefix = "SMSG";
|
||||
|
||||
message SecureMessage {
|
||||
// Must contain a HeaderAndBody message
|
||||
required bytes header_and_body = 1;
|
||||
// Signature of header_and_body
|
||||
required bytes signature = 2;
|
||||
}
|
||||
|
||||
// Supported "signature" schemes (both symmetric key and public key based)
|
||||
enum SigScheme {
|
||||
HMAC_SHA256 = 1;
|
||||
ECDSA_P256_SHA256 = 2;
|
||||
// Not recommended -- use ECDSA_P256_SHA256 instead
|
||||
RSA2048_SHA256 = 3;
|
||||
}
|
||||
|
||||
// Supported encryption schemes
|
||||
enum EncScheme {
|
||||
// No encryption
|
||||
NONE = 1;
|
||||
AES_256_CBC = 2;
|
||||
}
|
||||
|
||||
message Header {
|
||||
required SigScheme signature_scheme = 1;
|
||||
required EncScheme encryption_scheme = 2;
|
||||
// Identifies the verification key
|
||||
optional bytes verification_key_id = 3;
|
||||
// Identifies the decryption key
|
||||
optional bytes decryption_key_id = 4;
|
||||
// Encryption may use an IV
|
||||
optional bytes iv = 5;
|
||||
// Arbitrary per-protocol public data, to be sent with the plain-text header
|
||||
optional bytes public_metadata = 6;
|
||||
// The length of some associated data this is not sent in this SecureMessage,
|
||||
// but which will be bound to the signature.
|
||||
optional uint32 associated_data_length = 7 [default = 0];
|
||||
}
|
||||
|
||||
message HeaderAndBody {
|
||||
// Public data about this message (to be bound in the signature)
|
||||
required Header header = 1;
|
||||
// Payload data
|
||||
required bytes body = 2;
|
||||
}
|
||||
|
||||
// Must be kept wire-format compatible with HeaderAndBody. Provides the
|
||||
// SecureMessage code with a consistent wire-format representation that
|
||||
// remains stable irrespective of protobuf implementation choices. This
|
||||
// low-level representation of a HeaderAndBody should not be used by
|
||||
// any code outside of the SecureMessage library implementation/tests.
|
||||
message HeaderAndBodyInternal {
|
||||
// A raw (wire-format) byte encoding of a Header, suitable for hashing
|
||||
required bytes header = 1;
|
||||
// Payload data
|
||||
required bytes body = 2;
|
||||
}
|
||||
|
||||
// -------
|
||||
// The remainder of the messages defined here are provided only for
|
||||
// convenience. They are not needed for SecureMessage proper, but are
|
||||
// commonly useful wherever SecureMessage might be applied.
|
||||
// -------
|
||||
|
||||
// A list of supported public key types
|
||||
enum PublicKeyType {
|
||||
EC_P256 = 1;
|
||||
RSA2048 = 2;
|
||||
// 2048-bit MODP group 14, from RFC 3526
|
||||
DH2048_MODP = 3;
|
||||
}
|
||||
|
||||
// A convenience proto for encoding NIST P-256 elliptic curve public keys
|
||||
message EcP256PublicKey {
|
||||
// x and y are encoded in big-endian two's complement (slightly wasteful)
|
||||
// Client MUST verify (x,y) is a valid point on NIST P256
|
||||
required bytes x = 1;
|
||||
required bytes y = 2;
|
||||
}
|
||||
|
||||
// A convenience proto for encoding RSA public keys with small exponents
|
||||
message SimpleRsaPublicKey {
|
||||
// Encoded in big-endian two's complement
|
||||
required bytes n = 1;
|
||||
optional int32 e = 2 [default = 65537];
|
||||
}
|
||||
|
||||
// A convenience proto for encoding Diffie-Hellman public keys,
|
||||
// for use only when Elliptic Curve based key exchanges are not possible.
|
||||
// (Note that the group parameters must be specified separately)
|
||||
message DhPublicKey {
|
||||
// Big-endian two's complement encoded group element
|
||||
required bytes y = 1;
|
||||
}
|
||||
|
||||
message GenericPublicKey {
|
||||
required PublicKeyType type = 1;
|
||||
optional EcP256PublicKey ec_p256_public_key = 2;
|
||||
optional SimpleRsaPublicKey rsa2048_public_key = 3;
|
||||
// Use only as a last resort
|
||||
optional DhPublicKey dh2048_public_key = 4;
|
||||
}
|
||||
105
NearbyShare/ProtobufSource/ukey.proto
Normal file
105
NearbyShare/ProtobufSource/ukey.proto
Normal file
@@ -0,0 +1,105 @@
|
||||
// Copyright 2020 Google LLC
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
//
|
||||
// https://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package securegcm;
|
||||
|
||||
option optimize_for = LITE_RUNTIME;
|
||||
option java_package = "com.google.security.cryptauth.lib.securegcm";
|
||||
option java_outer_classname = "UkeyProto";
|
||||
|
||||
message Ukey2Message {
|
||||
enum Type {
|
||||
UNKNOWN_DO_NOT_USE = 0;
|
||||
ALERT = 1;
|
||||
CLIENT_INIT = 2;
|
||||
SERVER_INIT = 3;
|
||||
CLIENT_FINISH = 4;
|
||||
}
|
||||
|
||||
optional Type message_type = 1; // Identifies message type
|
||||
optional bytes message_data = 2; // Actual message, to be parsed according to
|
||||
// message_type
|
||||
}
|
||||
|
||||
message Ukey2Alert {
|
||||
enum AlertType {
|
||||
// Framing errors
|
||||
BAD_MESSAGE = 1; // The message could not be deserialized
|
||||
BAD_MESSAGE_TYPE = 2; // message_type has an undefined value
|
||||
INCORRECT_MESSAGE = 3; // message_type received does not correspond to
|
||||
// expected type at this stage of the protocol
|
||||
BAD_MESSAGE_DATA = 4; // Could not deserialize message_data as per
|
||||
// value inmessage_type
|
||||
|
||||
// ClientInit and ServerInit errors
|
||||
BAD_VERSION = 100; // version is invalid; server cannot find
|
||||
// suitable version to speak with client.
|
||||
BAD_RANDOM = 101; // Random data is missing or of incorrect
|
||||
// length
|
||||
BAD_HANDSHAKE_CIPHER = 102; // No suitable handshake ciphers were found
|
||||
BAD_NEXT_PROTOCOL = 103; // The next protocol is missing, unknown, or
|
||||
// unsupported
|
||||
BAD_PUBLIC_KEY = 104; // The public key could not be parsed
|
||||
|
||||
// Other errors
|
||||
INTERNAL_ERROR = 200; // An internal error has occurred. error_message
|
||||
// may contain additional details for logging
|
||||
// and debugging.
|
||||
}
|
||||
|
||||
optional AlertType type = 1;
|
||||
optional string error_message = 2;
|
||||
}
|
||||
|
||||
enum Ukey2HandshakeCipher {
|
||||
RESERVED = 0;
|
||||
P256_SHA512 = 100; // NIST P-256 used for ECDH, SHA512 used for
|
||||
// commitment
|
||||
CURVE25519_SHA512 = 200; // Curve 25519 used for ECDH, SHA512 used for
|
||||
// commitment
|
||||
}
|
||||
|
||||
message Ukey2ClientInit {
|
||||
optional int32 version = 1; // highest supported version for rollback
|
||||
// protection
|
||||
optional bytes random = 2; // random bytes for replay/reuse protection
|
||||
|
||||
// One commitment (hash of ClientFinished containing public key) per supported
|
||||
// cipher
|
||||
message CipherCommitment {
|
||||
optional Ukey2HandshakeCipher handshake_cipher = 1;
|
||||
optional bytes commitment = 2;
|
||||
}
|
||||
repeated CipherCommitment cipher_commitments = 3;
|
||||
|
||||
// Next protocol that the client wants to speak.
|
||||
optional string next_protocol = 4;
|
||||
}
|
||||
|
||||
message Ukey2ServerInit {
|
||||
optional int32 version = 1; // highest supported version for rollback
|
||||
// protection
|
||||
optional bytes random = 2; // random bytes for replay/reuse protection
|
||||
|
||||
// Selected Cipher and corresponding public key
|
||||
optional Ukey2HandshakeCipher handshake_cipher = 3;
|
||||
optional bytes public_key = 4;
|
||||
}
|
||||
|
||||
message Ukey2ClientFinished {
|
||||
optional bytes public_key = 1; // public key matching selected handshake
|
||||
// cipher
|
||||
}
|
||||
236
NearbyShare/ProtobufSource/wire_format.proto
Normal file
236
NearbyShare/ProtobufSource/wire_format.proto
Normal file
@@ -0,0 +1,236 @@
|
||||
// Copyright 2020 The Chromium Authors
|
||||
// Use of this source code is governed by a BSD-style license that can be
|
||||
// found in the LICENSE file.
|
||||
|
||||
// Brought from: //depot/google3/location/nearby/sharing/proto/wire_format.proto
|
||||
// At CL 317565061
|
||||
|
||||
syntax = "proto2";
|
||||
|
||||
package sharing.nearby;
|
||||
|
||||
// Required in Chrome.
|
||||
option optimize_for = LITE_RUNTIME;
|
||||
|
||||
// File metadata. Does not include the actual bytes of the file.
|
||||
// NEXT_ID=6
|
||||
message FileMetadata {
|
||||
enum Type {
|
||||
UNKNOWN = 0;
|
||||
IMAGE = 1;
|
||||
VIDEO = 2;
|
||||
APP = 3;
|
||||
AUDIO = 4;
|
||||
}
|
||||
|
||||
// The human readable name of this file (eg. 'Cookbook.pdf').
|
||||
optional string name = 1;
|
||||
|
||||
// The type of file (eg. 'IMAGE' from 'dog.jpg'). Specifying a type helps
|
||||
// provide a richer experience on the receiving side.
|
||||
optional Type type = 2 [default = UNKNOWN];
|
||||
|
||||
// The FILE payload id that will be sent as a follow up containing the actual
|
||||
// bytes of the file.
|
||||
optional int64 payload_id = 3;
|
||||
|
||||
// The total size of the file.
|
||||
optional int64 size = 4;
|
||||
|
||||
// The mimeType of file (eg. 'image/jpeg' from 'dog.jpg'). Specifying a
|
||||
// mimeType helps provide a richer experience on receiving side.
|
||||
optional string mime_type = 5 [default = "application/octet-stream"];
|
||||
|
||||
// A uuid for the attachment. Should be unique across all attachments.
|
||||
optional int64 id = 6;
|
||||
}
|
||||
|
||||
// NEXT_ID=5
|
||||
message TextMetadata {
|
||||
enum Type {
|
||||
UNKNOWN = 0;
|
||||
TEXT = 1;
|
||||
// Open with browsers.
|
||||
URL = 2;
|
||||
// Open with map apps.
|
||||
ADDRESS = 3;
|
||||
// Dial.
|
||||
PHONE_NUMBER = 4;
|
||||
}
|
||||
|
||||
// The title of the text content.
|
||||
optional string text_title = 2;
|
||||
|
||||
// The type of text (phone number, url, address, or plain text).
|
||||
optional Type type = 3 [default = UNKNOWN];
|
||||
|
||||
// The BYTE payload id that will be sent as a follow up containing the actual
|
||||
// bytes of the text.
|
||||
optional int64 payload_id = 4;
|
||||
|
||||
// The size of the text content.
|
||||
optional int64 size = 5;
|
||||
|
||||
// A uuid for the attachment. Should be unique across all attachments.
|
||||
optional int64 id = 6;
|
||||
}
|
||||
|
||||
// NEXT_ID=5
|
||||
message WifiCredentialsMetadata {
|
||||
enum SecurityType {
|
||||
UNKNOWN_SECURITY_TYPE = 0;
|
||||
OPEN = 1;
|
||||
WPA_PSK = 2;
|
||||
WEP = 3;
|
||||
}
|
||||
|
||||
// The Wifi network name. This will be sent in introduction.
|
||||
optional string ssid = 2;
|
||||
|
||||
// The security type of network (OPEN, WPA_PSK, WEP).
|
||||
optional SecurityType security_type = 3 [default = UNKNOWN_SECURITY_TYPE];
|
||||
|
||||
// The BYTE payload id that will be sent as a follow up containing the
|
||||
// password.
|
||||
optional int64 payload_id = 4;
|
||||
|
||||
// A uuid for the attachment. Should be unique across all attachments.
|
||||
optional int64 id = 5;
|
||||
}
|
||||
|
||||
// A frame used when sending messages over the wire.
|
||||
// NEXT_ID=3
|
||||
message Frame {
|
||||
enum Version {
|
||||
UNKNOWN_VERSION = 0;
|
||||
V1 = 1;
|
||||
}
|
||||
optional Version version = 1;
|
||||
|
||||
// Right now there's only 1 version, but if there are more, exactly one of
|
||||
// the following fields will be set.
|
||||
optional V1Frame v1 = 2;
|
||||
}
|
||||
|
||||
// NEXT_ID=7
|
||||
message V1Frame {
|
||||
enum FrameType {
|
||||
UNKNOWN_FRAME_TYPE = 0;
|
||||
INTRODUCTION = 1;
|
||||
RESPONSE = 2;
|
||||
PAIRED_KEY_ENCRYPTION = 3;
|
||||
PAIRED_KEY_RESULT = 4;
|
||||
CERTIFICATE_INFO = 5;
|
||||
CANCEL = 6;
|
||||
}
|
||||
|
||||
optional FrameType type = 1;
|
||||
|
||||
// Exactly one of the following fields will be set.
|
||||
optional IntroductionFrame introduction = 2;
|
||||
optional ConnectionResponseFrame connection_response = 3;
|
||||
optional PairedKeyEncryptionFrame paired_key_encryption = 4;
|
||||
optional PairedKeyResultFrame paired_key_result = 5;
|
||||
optional CertificateInfoFrame certificate_info = 6;
|
||||
}
|
||||
|
||||
// An introduction packet sent by the sending side. Contains a list of files
|
||||
// they'd like to share.
|
||||
// NEXT_ID=4
|
||||
message IntroductionFrame {
|
||||
repeated FileMetadata file_metadata = 1;
|
||||
repeated TextMetadata text_metadata = 2;
|
||||
// The required app package to open the content. May be null.
|
||||
optional string required_package = 3;
|
||||
repeated WifiCredentialsMetadata wifi_credentials_metadata = 4;
|
||||
}
|
||||
|
||||
// A response packet sent by the receiving side. Accepts or rejects the list of
|
||||
// files.
|
||||
// NEXT_ID=2
|
||||
message ConnectionResponseFrame {
|
||||
enum Status {
|
||||
UNKNOWN = 0;
|
||||
ACCEPT = 1;
|
||||
REJECT = 2;
|
||||
NOT_ENOUGH_SPACE = 3;
|
||||
UNSUPPORTED_ATTACHMENT_TYPE = 4;
|
||||
TIMED_OUT = 5;
|
||||
}
|
||||
|
||||
// The receiving side's response.
|
||||
optional Status status = 1;
|
||||
}
|
||||
|
||||
// A paired key encryption packet sent between devices, contains signed data.
|
||||
// NEXT_ID=3
|
||||
message PairedKeyEncryptionFrame {
|
||||
// The encrypted data in byte array format.
|
||||
optional bytes signed_data = 1;
|
||||
|
||||
// The hash of a certificate id.
|
||||
optional bytes secret_id_hash = 2;
|
||||
|
||||
// An optional encrypted data in byte array format.
|
||||
optional bytes optional_signed_data = 3;
|
||||
}
|
||||
|
||||
// A paired key verification result packet sent between devices.
|
||||
// NEXT_ID=2
|
||||
message PairedKeyResultFrame {
|
||||
enum Status {
|
||||
UNKNOWN = 0;
|
||||
SUCCESS = 1;
|
||||
FAIL = 2;
|
||||
UNABLE = 3;
|
||||
}
|
||||
|
||||
// The verification result.
|
||||
optional Status status = 1;
|
||||
}
|
||||
|
||||
// A package containing certificate info to be shared to remote device offline.
|
||||
// NEXT_ID=2
|
||||
message CertificateInfoFrame {
|
||||
// The public certificates to be shared with remote devices.
|
||||
repeated PublicCertificate public_certificate = 1;
|
||||
}
|
||||
|
||||
// A public certificate from the local device.
|
||||
// NEXT_ID=8
|
||||
message PublicCertificate {
|
||||
// The unique id of the public certificate.
|
||||
optional bytes secret_id = 1;
|
||||
|
||||
// A bytes representation of a Secret Key owned by contact, to decrypt the
|
||||
// metadata_key stored within the advertisement.
|
||||
optional bytes authenticity_key = 2;
|
||||
|
||||
// A bytes representation a public key of X509Certificate, owned by contact,
|
||||
// to decrypt encrypted UKEY2 (from Nearby Connections API) as a hand shake in
|
||||
// contact verification phase.
|
||||
optional bytes public_key = 3;
|
||||
|
||||
// The time in millis from epoch when this certificate becomes effective.
|
||||
optional int64 start_time = 4;
|
||||
|
||||
// The time in millis from epoch when this certificate expires.
|
||||
optional int64 end_time = 5;
|
||||
|
||||
// The encrypted metadata in bytes, contains personal information of the
|
||||
// device/user who created this certificate. Needs to be decrypted into bytes,
|
||||
// and converted back to EncryptedMetadata object to access fields.
|
||||
optional bytes encrypted_metadata_bytes = 6;
|
||||
|
||||
// The tag for verifying metadata_encryption_key.
|
||||
optional bytes metadata_encryption_key_tag = 7;
|
||||
}
|
||||
|
||||
// NEXT_ID=3
|
||||
message WifiCredentials {
|
||||
// Wi-Fi password.
|
||||
optional string password = 1;
|
||||
// True if the network is a hidden network that is not broadcasting its SSID.
|
||||
// Default is false.
|
||||
optional bool hidden_ssid = 2 [default = false];
|
||||
}
|
||||
Reference in New Issue
Block a user