예제 #1
0
파일: pack_ac.go 프로젝트: gitter-badger/ac
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
}
예제 #2
0
파일: pack_kx.go 프로젝트: gitter-badger/ac
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
}
예제 #3
0
파일: msg_ct.go 프로젝트: gitter-badger/ac
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
}
예제 #4
0
파일: msg_ct.go 프로젝트: gitter-badger/ac
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
}