Example #1
0
// we use PBKDF2 + SHA3 to derive a key out of the entropy with a crypto/rand salt
// TODO: implement fortuna to feed the PRNG
func CTADD_Handler(acMessageCtReq *AcCipherTextMessageRequest) (acMsgResponse *AcCipherTextMessageResponse, err error) {
	var responseType AcCipherTextMessageResponseAcCTRespMsgType
	responseType = AcCipherTextMessageResponse_CTR_ADD

	reqChan := acMessageCtReq.GetChannel()
	reqNick := acMessageCtReq.GetNick()
	reqServ := acMessageCtReq.GetServer()
	reqBlob := acMessageCtReq.GetBlob()

	acutl.DebugLog.Printf("(CALL) CTADD %s/%s from %s:'%s' (%s)\n", reqChan, reqServ, reqNick, reqBlob)

	if len(reqChan) == 0 || len(reqNick) == 0 || len(reqServ) == 0 {
		retErr := &acutl.AcError{Value: -1, Msg: "CTADD_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[!]) CTADD -> (-1) ! %s\n", retErr.Error())
		return acMsgResponse, retErr
	}

	// lets derive the key.
	//    randsalt :=  rand.Read()
	//    func (skgen ACSecretKeyGen) Init(input []byte, channel []byte, nick []byte, serv []byte) {
	skgen := new(ackp.SecretKeyGen)
	err = skgen.Init([]byte(reqBlob), []byte(reqChan), []byte(reqNick), []byte(reqServ))
	if err != nil {
		retErr := &acutl.AcError{Value: -2, Msg: "CTADD_Handler(): SK generator fail!", Err: err}
		acMsgResponse = &AcCipherTextMessageResponse{
			Type:      &responseType,
			Bada:      proto.Bool(false),
			ErrorCode: proto.Int32(-2),
		}
		acutl.DebugLog.Printf("(RET[!]) CTADD -> (-2) ! %s\n", retErr.Error())
		return acMsgResponse, retErr
	}

	// XXX TODO: handle error or remove it...
	acctx, _ := ackp.CreateACContext([]byte(reqChan), 0)

	key := make([]byte, 32)
	io.ReadFull(skgen, key)

	newRnd := make([]byte, len(key))
	_, err = rand.Read(newRnd)
	if err != nil {
		retErr := &acutl.AcError{Value: -3, Msg: "CTADD_Handler(): randomness fail!", Err: err}
		acMsgResponse = &AcCipherTextMessageResponse{
			Type:      &responseType,
			Bada:      proto.Bool(false),
			ErrorCode: proto.Int32(-3),
		}
		return acMsgResponse, retErr
	}

	acctx.SetKey(key)
	// XOR the key...
	acctx.RndKey(newRnd)

	ackp.ACmap.SetSKMapEntry(reqServ, reqChan, acctx)
	ackp.ACmap.SetRDMapEntry(reqServ, reqChan, newRnd)

	acMsgResponse = &AcCipherTextMessageResponse{
		Type:      &responseType,
		Bada:      proto.Bool(true),
		ErrorCode: proto.Int32(0),
		//Blob:      []byte("OK"),
		Blob: [][]byte{[]byte("OK")}, // this is an array of []byte
	}

	acutl.DebugLog.Printf("(RET) CTADD -> (0) ! %s/%s key added (entropy: '%s')\n", reqServ, reqChan, reqBlob)
	return acMsgResponse, nil
}
Example #2
0
func OpenKXMessageNACL(peerPubkey, myPrivkey *[32]byte, cmsg, channel, myNick, peerNick []byte) (context *ackp.SecKey, SecRnd []byte, err error) {
	// check that we are indeed
	if peerPubkey == nil || myPrivkey == nil {
		//return nil, acprotoError(-1, "OpenKXMessage().invalidPubPrivKeys(): ", err)
		return nil, nil, &acutl.AcError{Value: -1, Msg: "OpenKXMessageNACL().invalidPubPrivKeys(): ", Err: err}
	}

	b64, err := acutl.B64DecodeData(cmsg)
	if err != nil {
		return nil, nil, &acutl.AcError{Value: -2, Msg: "OpenKXMessageNACL(): ", Err: err}
	}

	cnonce, myHdr, ciphertext, err := unpackMessageKX(b64)
	if err != nil {
		return nil, nil, &acutl.AcError{Value: -3, Msg: "OpenKXMessageNACL(): ", Err: err}
	}

	// XXX TODO: exact opposite of the one in CreateKXMessage
	kx_channel := IsChannelOrPriv(channel, peerNick, myNick)

	// XXX TODO: we should add the header like <ackx:peerNick> to avoid replay from
	// other nickname on the channel... nonce building!
	_, noncebyte, err := BuildNonceKX(cnonce, kx_channel, peerNick, myNick, myHdr)
	if err != nil {
		return nil, nil, &acutl.AcError{Value: -4, Msg: "OpenKXMessageNACL(): ", Err: err}
	}

	packed, ok := box.Open(nil, ciphertext, noncebyte, peerPubkey, myPrivkey)
	if ok == false {
		return nil, nil, &acutl.AcError{Value: -5, Msg: "OpenKXMessageNACL().BoxOpen(): ", Err: nil}
	}

	out, err := acutl.DecompressData(packed)
	if err != nil {
		return nil, nil, &acutl.AcError{Value: -6, Msg: "OpenKXMessageNACL(): ", Err: err}
	}

	//fmt.Fprintf(os.Stderr, "OPEN KX KEY: %s\n", hex.EncodeToString(out))
	// XXX TODO are we at the end of the nonce value..
	context, err = ackp.CreateACContext(channel, cnonce+1)
	if err != nil {
		return nil, nil, &acutl.AcError{Value: -7, Msg: "OpenKXMessage().CreateACContext(): ", Err: err}
	}

	// XXX TODO
	// get RANDOMNESS bytes, return the random bytes
	newRnd, err := acutl.GetRandomBytes(context.GetKeyLen())
	if err != nil {
		return nil, nil, &acutl.AcError{Value: -8, Msg: "OpenKXMessage() no randomness to protect the key in memory: ", Err: err}
	}
	/*
		newRnd := make([]byte, len(context.key))
		_, err = rand.Read(newRnd)
	*/

	// XXX TODO: check the extracted buffer size... to sure we're not copying
	// too much into a restricted buffer...
	//copy(context.key[:], out)
	context.SetKey(out)

	// Xor the key now..
	context.RndKey(newRnd)

	// increase nonce based on the message nonce value
	context.IncNonce(cnonce)

	return context, newRnd, nil
}