예제 #1
0
파일: msgct.go 프로젝트: unix4fun/ac
func (ct *ACCtMessage) HandlerCTADD() (msgReply []byte, err error) {
	icutl.DebugLog.Printf("CALL [%p] HandlerCTADD([%d/%s/%s] <%s> %08s)\n",
		ct,
		ct.Type,
		ct.Server,
		ct.Channel,
		ct.Nick,
		ct.Blob)

	err = ct.validate()
	if err != nil {
		msgReply, _ = json.Marshal(&ACCtReply{
			Type:  R_CTADD,
			Bada:  false,
			Errno: -1,
			Blob:  err.Error(),
		})
		icutl.DebugLog.Printf("RET [%p] HandlerCTADD([%d/%s/%s] <%s> %04s) -> [Error: %s]\n",
			ct,
			ct.Type,
			ct.Server,
			ct.Channel,
			ct.Nick,
			ct.Blob, err.Error())
		return
	}

	// lets derive the key.
	//    randsalt :=  rand.Read()
	//    func (skgen ACSecretKeyGen) Init(input []byte, channel []byte, nick []byte, serv []byte) {
	skgen := new(ickp.KeyGenerator)
	err = skgen.Init([]byte(ct.Blob), []byte(ct.Channel), []byte(ct.Nick), []byte(ct.Server))
	if err != nil {
		msgReply, _ = json.Marshal(&ACCtReply{
			Type:  R_CTADD,
			Bada:  false,
			Errno: -2,
			Blob:  err.Error(),
		})
		icutl.DebugLog.Printf("RET [%p] HandlerCTADD([%d/%s/%s] <%s> %04s) -> [Error: %s]\n",
			ct,
			ct.Type,
			ct.Server,
			ct.Channel,
			ct.Nick,
			ct.Blob, err.Error())
		return
	}

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

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

	newRnd := make([]byte, len(key))
	_, err = rand.Read(newRnd)
	if err != nil {
		msgReply, _ = json.Marshal(&ACCtReply{
			Type:  R_CTADD,
			Bada:  false,
			Errno: -3,
			Blob:  err.Error(),
		})
		icutl.DebugLog.Printf("RET [%p] HandlerCTADD([%d/%s/%s] <%s> %04s) -> [Error: %s]\n",
			ct,
			ct.Type,
			ct.Server,
			ct.Channel,
			ct.Nick,
			ct.Blob, err.Error())
		return
	}

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

	ickp.ACmap.SetSKMapEntry(ct.Server, ct.Channel, acctx)
	ickp.ACmap.SetRDMapEntry(ct.Server, ct.Channel, newRnd)

	msgReply, _ = json.Marshal(&ACCtReply{
		Type:  R_CTADD,
		Bada:  true,
		Errno: 0,
		Blob:  "OK",
	})
	icutl.DebugLog.Printf("RET [%p] HandlerCTADD([%d/%s/%s] <%s> %04s) -> [OK]\n",
		ct,
		ct.Type,
		ct.Server,
		ct.Channel,
		ct.Nick,
		ct.Blob)
	return
}
예제 #2
0
파일: pack_kx.go 프로젝트: unix4fun/ac
func OpenKXMessageNACL(peerPubkey, myPrivkey *[32]byte, cmsg, channel, myNick, peerNick []byte) (context *ickp.SecretKey, SecRnd []byte, err error) {
	// check that we are indeed
	if peerPubkey == nil || myPrivkey == nil {
		//return nil, acprotoError(-1, "OpenKXMessage().invalidPubPrivKeys(): ", err)
		return nil, nil, &icutl.AcError{Value: -1, Msg: "OpenKXMessageNACL().invalidPubPrivKeys(): ", Err: err}
	}

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

	cnonce, myHdr, ciphertext, err := unpackMessageKX(b64)
	if err != nil {
		return nil, nil, &icutl.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, &icutl.AcError{Value: -4, Msg: "OpenKXMessageNACL(): ", Err: err}
	}

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

	out, err := icutl.DecompressData(packed)
	if err != nil {
		return nil, nil, &icutl.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 = ickp.CreateACContext(channel, cnonce+1)
	if err != nil {
		return nil, nil, &icutl.AcError{Value: -7, Msg: "OpenKXMessage().CreateACContext(): ", Err: err}
	}

	// XXX TODO
	// get RANDOMNESS bytes, return the random bytes
	newRnd, err := icutl.GetRandomBytes(context.GetKeyLen())
	if err != nil {
		return nil, nil, &icutl.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
}