func CreateACMessageNACL(context *ackp.SecKey, rnd, msg, myNick []byte) (out []byte, err error) { //var noncebyte [24]byte /* lets build our header */ myHdr, intHdr, err := BuildHeader([]byte(msgHdrAC)) if err != nil { return nil, &acutl.AcError{Value: -1, Msg: "CreateACMessageNACL().BuildHeader(): ", Err: err} } // first let's compress myBody, err := acutl.CompressData(msg) if err != nil { return nil, &acutl.AcError{Value: -2, Msg: "CreateACMessageNACL().CompressData(): ", Err: err} } //BuildNonceAC(inonce uint32, bob, mynick, myhdr []byte) (nonce []byte, noncebyte *[24]byte, err error) _, noncebyte, err := BuildNonceAC(context.GetNonce(), context.GetBob(), myNick, myHdr) // OPEN the key // XXX new to check rnd and context.key are the same size /* for j := 0; j < len(rnd); j++ { context.key[j] = context.key[j] ^ rnd[j] } */ context.RndKey(rnd) // encrypt myCipher := secretbox.Seal(nil, myBody, noncebyte, context.GetSealKey()) // close the key context.RndKey(rnd) /* for j := 0; j < len(rnd); j++ { context.key[j] = context.key[j] ^ rnd[j] } */ // XXX error checking out, err = packMessageAC(&intHdr, context.GetNonce(), &myCipher) //fmt.Fprintf(os.Stderr, "NACL PB == AC MSG OUT[%d]: %s\n", len(out), out) //context.nonce++ context.IncNonce(0) return out, nil }
func OpenACMessageNACL(context *ackp.SecKey, rnd, cmsg, peerNick, myNick []byte) (out []byte, err error) { fmt.Fprintf(os.Stderr, "OpenACMessageNACL()\n") b64, err := acutl.B64DecodeData(cmsg) if err != nil { return nil, &acutl.AcError{Value: -1, Msg: "OpenACMessageNACL(): ", Err: err} } cnonce, myHdr, ciphertext, err := unpackMessageAC(b64) if err != nil { return nil, &acutl.AcError{Value: -2, Msg: "OpenACMessageNACL(): ", Err: err} } // XXX this is to handle private message instead of channel communication // as the destination are assymetrical eau's dst is frl and frl's dst is eau // ac_bob := context.GetBob() ok_bob, _ := IsValidChannelName(ac_bob) fmt.Fprintf(os.Stderr, "[+] OpenACMessage: is %s a valid channel: %t\n", ac_bob, ok_bob) if ok_bob == false && len(myNick) > 0 { ac_bob = myNick } /* let's build the nonce */ //BuildNonceAC(inonce uint32, bob, mynick, myhdr []byte) (nonce []byte, noncebyte *[24]byte, err error) _, noncebyte, err := BuildNonceAC(cnonce, ac_bob, peerNick, myHdr) // OPEN the key context.RndKey(rnd) // XXX new to check rnd and context.key are the same size /* for j := 0; j < len(rnd); j++ { context.key[j] = context.key[j] ^ rnd[j] } */ packed, ok := secretbox.Open(nil, ciphertext, noncebyte, context.GetSealKey()) // Close the key context.RndKey(rnd) /* for j := 0; j < len(rnd); j++ { context.key[j] = context.key[j] ^ rnd[j] } */ if ok == false { //return nil, acprotoError(1, "OpenACMessage().SecretOpen(): false ", nil) return nil, &acutl.AcError{Value: -3, Msg: "OpenACMessageNACL().SecretOpen(): ", Err: nil} } out, err = acutl.DecompressData(packed) if err != nil { return nil, &acutl.AcError{Value: -3, Msg: "OpenACMessageNACL().DecompressData(): ", Err: err} } //nonceval = acIn.GetNonce() // update the nonce value /* if cnonce > context.nonce { context.nonce = cnonce + 1 } else { context.nonce++ } */ context.IncNonce(cnonce) return out, nil //return nil, nil }
func CTOPEN_Handler(acMessageCtReq *AcCipherTextMessageRequest) (acMsgResponse *AcCipherTextMessageResponse, err error) { var responseType AcCipherTextMessageResponseAcCTRespMsgType responseType = AcCipherTextMessageResponse_CTR_OPEN var acctx *ackp.SecKey channel := acMessageCtReq.GetChannel() peernick := acMessageCtReq.GetNick() reqServ := acMessageCtReq.GetServer() blob := acMessageCtReq.GetBlob() reqOpt := acMessageCtReq.GetOpt() // XXX will be used for myNick acutl.DebugLog.Printf("(CALL) CTOPEN %s/%s from %s:'%s' (%s)\n", channel, reqServ, peernick, blob, reqOpt) if len(channel) == 0 || len(peernick) == 0 || len(blob) == 0 { retErr := &acutl.AcError{Value: -1, Msg: "CTOPEN_Handler().args(channel|serv|mynick): 0 bytes", Err: nil} acMsgResponse = &AcCipherTextMessageResponse{ Type: &responseType, Bada: proto.Bool(false), ErrorCode: proto.Int32(-1), } acutl.DebugLog.Printf("(RET[!]) CTOPEN -> (-1) ! %s\n", retErr.Error()) return acMsgResponse, retErr } //acctx, ok_a := Sk[channel] acctx, ok_a := ackp.ACmap.GetSKMapEntry(reqServ, channel) if ok_a == false { retErr := &acutl.AcError{Value: -2, Msg: "CTOPEN_Handler(): no SKMap Entry found!", Err: nil} acMsgResponse = &AcCipherTextMessageResponse{ Type: &responseType, Bada: proto.Bool(false), ErrorCode: proto.Int32(-2), } acutl.DebugLog.Printf("(RET[!]) CTOPEN -> (-2) ! %s\n", retErr.Error()) return acMsgResponse, retErr } acrnd, ok_b := ackp.ACmap.GetRDMapEntry(reqServ, channel) if ok_b == false { retErr := &acutl.AcError{Value: -3, Msg: "CTOPEN_Handler(): no RDMap Entry found!", Err: nil} acMsgResponse = &AcCipherTextMessageResponse{ Type: &responseType, Bada: proto.Bool(false), ErrorCode: proto.Int32(-3), } acutl.DebugLog.Printf("(RET[!]) CTOPEN -> (-3) ! %s\n", retErr.Error()) return acMsgResponse, retErr } //func OpenACMessage(context * SecKey, cmsg, peerNick []byte) (out []byte, err error) { // XXX TODO: use reqOpt accordingly out, err := accp.OpenACMessageNACL(acctx, acrnd, blob, []byte(peernick), []byte(reqOpt)) if err != nil { retErr := &acutl.AcError{Value: -4, Msg: "CTOPEN_Handler(): OpenACMessageNACL() error!", Err: err} acMsgResponse = &AcCipherTextMessageResponse{ Type: &responseType, Bada: proto.Bool(false), ErrorCode: proto.Int32(-4), } acutl.DebugLog.Printf("(RET[!]) CTOPEN -> (-4) ! %s\n", retErr.Error()) return acMsgResponse, retErr } acMsgResponse = &AcCipherTextMessageResponse{ Type: &responseType, Bada: proto.Bool(true), ErrorCode: proto.Int32(0), Nonce: proto.Uint32(acctx.GetNonce()), Blob: [][]byte{out}, } acutl.DebugLog.Printf("(RET) CTOPEN -> (0) ! %s/%s %s's msg opened\n", reqServ, channel, peernick) return acMsgResponse, nil }
func CTSEAL_Handler(acMessageCtReq *AcCipherTextMessageRequest) (acMsgResponse *AcCipherTextMessageResponse, err error) { var responseType AcCipherTextMessageResponseAcCTRespMsgType responseType = AcCipherTextMessageResponse_CTR_SEAL var acctx *ackp.SecKey var acBlobArray [][]byte var out []byte var reqBlobTmp []byte reqChan := acMessageCtReq.GetChannel() myNick := acMessageCtReq.GetNick() reqServ := acMessageCtReq.GetServer() reqBlob := acMessageCtReq.GetBlob() acutl.DebugLog.Printf("(CALL) CTSEAL (%s/%s %s:'%s')\n", reqChan, reqServ, myNick, reqBlob) if len(reqChan) == 0 || len(myNick) == 0 || len(reqBlob) == 0 { retErr := &acutl.AcError{Value: -1, Msg: "CTSEAL_Handler().args(channel|serv|mynick): 0 bytes", Err: nil} acMsgResponse = &AcCipherTextMessageResponse{ Type: &responseType, Bada: proto.Bool(false), ErrorCode: proto.Int32(-1), } acutl.DebugLog.Printf("(RET[!]) CTSEAL -> (-1) ! %s\n", retErr.Error()) return acMsgResponse, retErr } acctx, ok_a := ackp.ACmap.GetSKMapEntry(reqServ, reqChan) if ok_a == false { retErr := &acutl.AcError{Value: -2, Msg: "CTSEAL_Handler(): no SKMap found!", Err: nil} acMsgResponse = &AcCipherTextMessageResponse{ Type: &responseType, Bada: proto.Bool(false), ErrorCode: proto.Int32(-2), } acutl.DebugLog.Printf("(RET[!]) CTSEAL -> (-2) ! %s\n", retErr.Error()) return acMsgResponse, retErr } acrnd, ok_b := ackp.ACmap.GetRDMapEntry(reqServ, reqChan) if ok_b == false { retErr := &acutl.AcError{Value: -3, Msg: "CTSEAL_Handler(): no RDMap found!", Err: nil} acMsgResponse = &AcCipherTextMessageResponse{ Type: &responseType, Bada: proto.Bool(false), ErrorCode: proto.Int32(-3), } acutl.DebugLog.Printf("(RET[!]) CTSEAL -> (-3) ! %s\n", retErr.Error()) return acMsgResponse, retErr } // XXX test here for message length and send multiple encrypted messages // TODO: dont hardcode the limits but well it's a first try // back if the original message is too long. /* if len(out)+14+len(reqChan) > 512 { fmt.Fprintf(os.Stderr, "MESSAGE WAYYYYYY TOO LONG LET's SPLIT AND BUILD SEVERAL") } */ //tmpBlobLen := len(reqBlob) //:nick!user@host PRIVMSG target :<usable bytes><CRLF> msgLen := accp.PredictLenNACL(reqBlob) + len(reqChan) + 14 nBlock := msgLen/410 + 1 //for msgLen, nBlock := accp.PredictLenNACL(tmpBlobLen)+len(reqChan)+14, 1; msgLen > 510; msgLen, nBlock = accp.PredictLenNACL(reqBlob)+len(reqChan)+14, nBlock+1 { /* for ; msgLen > 510; msgLen, nBlock = (accp.PredictLenNACL(reqBlob)+len(reqChan)+14)/nBlock, nBlock+1 { fmt.Fprintf(os.Stderr, ">>block size: %d numblock: %d\n", msgLen, nBlock) } nBlock-- */ // BUG HERE with offsets... for j, bSize, bAll, bPtr := 0, len(reqBlob)/nBlock, len(reqBlob), 0; j < nBlock; j, bPtr = j+1, bPtr+bSize { if bPtr+bSize+1 >= bAll { reqBlobTmp = reqBlob[bPtr:] //fmt.Fprintf(os.Stderr, "** %d block[%d:%d]: %s \n", j, bPtr, bAll, reqBlobTmp) //fmt.Fprintf(os.Stderr, ">> %d => %c || %d => %c\n", bAll, reqBlob[bAll-1], bAll+1, reqBlob[bAll+1]) //reqBlob[bPtr:bAll] } else { reqBlobTmp = reqBlob[bPtr : bPtr+bSize] //fmt.Fprintf(os.Stderr, ">>#%d block[%d:%d]: %s \n", j, bPtr, bPtr+bSize, reqBlobTmp) //reqBlob[bPtr : bPtr+bSize] } // END OF ELSE //fmt.Fprintf(os.Stderr, ">> NEW #%d block[%d:%d]: %s \n", j, bPtr, bPtr+len(reqBlobTmp), reqBlobTmp) out, err = accp.CreateACMessageNACL(acctx, acrnd, reqBlobTmp, []byte(myNick)) if err != nil { retErr := &acutl.AcError{Value: -4, Msg: "CTSEAL_Handler(): CreateACMessageNACL()!", Err: err} acMsgResponse = &AcCipherTextMessageResponse{ Type: &responseType, Bada: proto.Bool(false), ErrorCode: proto.Int32(-4), } acutl.DebugLog.Printf("(RET[!]) CTSEAL -> (-4) ! %s\n", retErr.Error()) return acMsgResponse, retErr } acBlobArray = append(acBlobArray, out) } // END OF FOR acMsgResponse = &AcCipherTextMessageResponse{ Type: &responseType, Bada: proto.Bool(true), ErrorCode: proto.Int32(0), // should be good enough for now... but better have a separate field with correct type.. Nonce: proto.Uint32(acctx.GetNonce()), Blob: acBlobArray, } //fmt.Fprintf(os.Stderr, "[+] CTSEAL -> (R) 0 ! %s/%s %s's msg sealed\n", reqServ, reqChan, myNick) acutl.DebugLog.Printf("(RET) CTSEAL -> (0) ! %s/%s %s's msg sealed\n", reqServ, reqChan, myNick) return acMsgResponse, nil }
func CreateKXMessageNACL(context *ackp.SecKey, rnd []byte, peerPubkey, myPrivkey *[32]byte, channel, myNick, peerNick []byte) (out []byte, err error) { /* lets build our header */ myHdr, intHdr, err := BuildHeader([]byte(msgHdrKX)) if err != nil { return nil, &acutl.AcError{Value: -1, Msg: "CreateKXMessageNACL().BuildHeader(): ", Err: err} } // Open the key context.RndKey(rnd) //fmt.Fprintf(os.Stderr, "CREATE KX KEY: %s\n", hex.EncodeToString(context.key[:])) // first let's compress myBody, err := acutl.CompressData(context.GetKey()) if err != nil { return nil, &acutl.AcError{Value: -2, Msg: "CreateKXMessageNACL().CompressData(): ", Err: err} } // Close the key context.RndKey(rnd) //fmt.Fprintf(os.Stderr, "channel: %s context.bob: %s\n", channel, context.bob) kx_channel := IsChannelOrPriv(channel, myNick, peerNick) // XXX i can probably use context.bob instead of a specific channel specification... //BuildNonceAC(inonce uint32, bob, mynick, myhdr []byte) (nonce []byte, noncebyte *[24]byte, err error) _, noncebyte, err := BuildNonceKX(context.GetNonce(), kx_channel, myNick, peerNick, myHdr) //fmt.Fprintf(os.Stderr, "peerpk : %p myprivkey: %p\n", peerPubkey, myPrivkey) // XXX TODO: need serious cleanup and error checking!! //fmt.Fprintf(os.Stderr, "body.Bytes(): %p, noncebyte: %p, peerPub: %p myPriv: %p\n", myBody, &noncebyte, peerPubkey, myPrivkey) cipherKex := box.Seal(nil, myBody, noncebyte, peerPubkey, myPrivkey) //func packMessageKX(hdr, nonce *uint32, dst, blob *[]byte) (out []byte, err error) { out, err = packMessageKX(&intHdr, context.GetNonce(), peerNick, cipherKex) if err != nil { return nil, &acutl.AcError{Value: -3, Msg: "CreateKXMessageNACL().packMessageKX(): ", Err: err} } //context.nonce++ context.IncNonce(0) return }