// SendAuthenticationResult responds to an existed authentication Proof // Prerequisites: // * Must have previously connected to a service // * channel must be of type auth func (oc *OpenConnection) SendAuthenticationResult(channel int32, accepted bool, isKnownContact bool) { defer utils.RecoverFromError() messageBuilder := new(MessageBuilder) data, err := messageBuilder.AuthResult(accepted, isKnownContact) utils.CheckError(err) oc.rni.SendRicochetPacket(oc.conn, channel, data) }
// SendMessage sends a Chat Message (message) to a give Channel (channel). // Prerequisites: // * Must have previously connected and authenticated to a service // * Must have established a known contact status with the other service // * Must have previously opened channel with OpenChanel of type im.ricochet.chat func (oc *OpenConnection) SendMessage(channel int32, message string) { defer utils.RecoverFromError() messageBuilder := new(MessageBuilder) data, err := messageBuilder.ChatMessage(message, 0) utils.CheckError(err) oc.rni.SendRicochetPacket(oc.conn, channel, data) }
// RejectOpenChannel acknowledges a rejects a previously received open channel message // Prerequisites: // * Must have previously connected func (oc *OpenConnection) RejectOpenChannel(channel int32, errortype string) { defer utils.RecoverFromError() messageBuilder := new(MessageBuilder) data, err := messageBuilder.RejectOpenChannel(channel, errortype) utils.CheckError(err) oc.rni.SendRicochetPacket(oc.conn, 0, data) }
// OpenChatChannel opens a new chat channel with the given id // Prerequisites: // * Must have previously connected to a service // * If acting as the client, id must be odd, else even func (oc *OpenConnection) OpenChatChannel(channel int32) { defer utils.RecoverFromError() messageBuilder := new(MessageBuilder) data, err := messageBuilder.OpenChannel(channel, "im.ricochet.chat") utils.CheckError(err) oc.setChannel(channel, "im.ricochet.chat") oc.rni.SendRicochetPacket(oc.conn, 0, data) }
// AckContactRequest responds to contact request from a client // Prerequisites: // * Must have previously connected and authenticated to a service // * Must have previously received a Contact Request func (oc *OpenConnection) AckContactRequest(channel int32, status string) { defer utils.RecoverFromError() messageBuilder := new(MessageBuilder) data, err := messageBuilder.ReplyToContactRequest(channel, status) utils.CheckError(err) oc.setChannel(channel, "im.ricochet.contact.request") oc.rni.SendRicochetPacket(oc.conn, channel, data) }
// SendContactRequest initiates a contact request to the server. // Prerequisites: // * Must have previously connected and authenticated to a service func (oc *OpenConnection) SendContactRequest(channel int32, nick string, message string) { defer utils.RecoverFromError() messageBuilder := new(MessageBuilder) data, err := messageBuilder.OpenContactRequestChannel(channel, nick, message) utils.CheckError(err) oc.setChannel(channel, "im.ricochet.contact.request") oc.rni.SendRicochetPacket(oc.conn, 0, data) }
// Authenticate opens an Authentication Channel and send a client cookie // Prerequisites: // * Must have previously connected to a service func (oc *OpenConnection) Authenticate(channel int32) { defer utils.RecoverFromError() oc.authHandler[channel] = new(AuthenticationHandler) messageBuilder := new(MessageBuilder) data, err := messageBuilder.OpenAuthenticationChannel(channel, oc.authHandler[channel].GenClientCookie()) utils.CheckError(err) oc.setChannel(channel, "im.ricochet.auth.hidden-service") oc.rni.SendRicochetPacket(oc.conn, 0, data) }
// OpenAuthenticationChannel constructs a message which will reuqest to open a channel for // authentication on the given channelID, with the given cookie func (mb *MessageBuilder) OpenAuthenticationChannel(channelID int32, clientCookie [16]byte) ([]byte, error) { oc := &Protocol_Data_Control.OpenChannel{ ChannelIdentifier: proto.Int32(channelID), ChannelType: proto.String("im.ricochet.auth.hidden-service"), } err := proto.SetExtension(oc, Protocol_Data_AuthHiddenService.E_ClientCookie, clientCookie[:]) utils.CheckError(err) pc := &Protocol_Data_Control.Packet{ OpenChannel: oc, } return proto.Marshal(pc) }
// ConfirmAuthChannel constructs a message to acknowledge a previous open channel operation. func (mb *MessageBuilder) ConfirmAuthChannel(channelID int32, serverCookie [16]byte) ([]byte, error) { cr := &Protocol_Data_Control.ChannelResult{ ChannelIdentifier: proto.Int32(channelID), Opened: proto.Bool(true), } err := proto.SetExtension(cr, Protocol_Data_AuthHiddenService.E_ServerCookie, serverCookie[:]) utils.CheckError(err) pc := &Protocol_Data_Control.Packet{ ChannelResult: cr, } return proto.Marshal(pc) }
// SendProof sends an authentication proof in response to a challenge. // Prerequisites: // * Must have previously connected to a service // * channel must be of type auth func (oc *OpenConnection) SendProof(channel int32, serverCookie [16]byte, publicKeyBytes []byte, privateKey *rsa.PrivateKey) { if oc.authHandler[channel] == nil { return // NoOp } oc.authHandler[channel].AddServerCookie(serverCookie[:]) challenge := oc.authHandler[channel].GenChallenge(oc.MyHostname, oc.OtherHostname) signature, _ := rsa.SignPKCS1v15(nil, privateKey, crypto.SHA256, challenge) defer utils.RecoverFromError() messageBuilder := new(MessageBuilder) data, err := messageBuilder.Proof(publicKeyBytes, signature) utils.CheckError(err) oc.rni.SendRicochetPacket(oc.conn, channel, data) }
// ReplyToContactRequestOnResponse constructs a message to acknowledge contact request func (mb *MessageBuilder) ReplyToContactRequestOnResponse(channelID int32, status string) ([]byte, error) { cr := &Protocol_Data_Control.ChannelResult{ ChannelIdentifier: proto.Int32(channelID), Opened: proto.Bool(true), } statusNum := Protocol_Data_ContactRequest.Response_Status_value[status] responseStatus := Protocol_Data_ContactRequest.Response_Status(statusNum) contactRequest := &Protocol_Data_ContactRequest.Response{ Status: &responseStatus, } err := proto.SetExtension(cr, Protocol_Data_ContactRequest.E_Response, contactRequest) utils.CheckError(err) pc := &Protocol_Data_Control.Packet{ ChannelResult: cr, } return proto.Marshal(pc) }
// OpenContactRequestChannel contructs a message which will reuqest to open a channel for // a contact request on the given channelID, with the given nick and message. func (mb *MessageBuilder) OpenContactRequestChannel(channelID int32, nick string, message string) ([]byte, error) { // Construct a Contact Request Channel oc := &Protocol_Data_Control.OpenChannel{ ChannelIdentifier: proto.Int32(channelID), ChannelType: proto.String("im.ricochet.contact.request"), } contactRequest := &Protocol_Data_ContactRequest.ContactRequest{ Nickname: proto.String(nick), MessageText: proto.String(message), } err := proto.SetExtension(oc, Protocol_Data_ContactRequest.E_ContactRequest, contactRequest) utils.CheckError(err) pc := &Protocol_Data_Control.Packet{ OpenChannel: oc, } return proto.Marshal(pc) }