github.com/jlmucb/cloudproxy@v0.0.0-20170830161738-b5aa0b619bc4/go/apps/mixnet/circuit.go (about) 1 // Copyright (c) 2016, Google Inc. All rights reserved. 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package mixnet 16 17 import ( 18 "crypto/rand" 19 "encoding/binary" 20 "errors" 21 "io" 22 23 "golang.org/x/crypto/nacl/box" 24 25 "github.com/jlmucb/cloudproxy/go/tao" 26 ) 27 28 // A circuit carries cells 29 type Circuit struct { 30 conn *Conn 31 id uint64 32 cells chan []byte 33 errs chan error 34 next *Circuit 35 entry bool 36 exit bool 37 forward bool 38 39 peerKey *[32]byte 40 publicKey *[32]byte 41 privateKey *[32]byte 42 sharedKey *[32]byte 43 } 44 45 // A circuit now encrypts for the exit circuit. The key is assumed to be available 46 // through "peerKey", and publicKey and privateKey are the keys are local keys 47 // used to perform diffiehellman with peerKey. The keys are optional. 48 func NewCircuit(conn *Conn, id uint64, entry, exit, forward bool) *Circuit { 49 return &Circuit{ 50 conn: conn, 51 id: id, 52 cells: make(chan []byte, 2), 53 errs: make(chan error, 2), 54 entry: entry, 55 exit: exit, 56 forward: forward, 57 } 58 } 59 60 func (c *Circuit) SetKeys(peerKey, publicKey, privateKey *[32]byte) { 61 var sharedKey [32]byte 62 box.Precompute(&sharedKey, peerKey, privateKey) 63 c.peerKey = peerKey 64 c.publicKey = publicKey 65 c.privateKey = privateKey 66 c.sharedKey = &sharedKey 67 } 68 69 func (c *Circuit) Encrypt(msg []byte) []byte { 70 var nonce [24]byte 71 rand.Read(nonce[:]) 72 boxed := box.SealAfterPrecomputation(nil, msg, &nonce, c.sharedKey) 73 boxed = append(nonce[:], boxed...) 74 return boxed 75 } 76 77 func (c *Circuit) Decrypt(boxed []byte) ([]byte, bool) { 78 var nonce [24]byte 79 copy(nonce[:], boxed[:24]) 80 return box.OpenAfterPrecomputation(nil, boxed[24:], &nonce, c.sharedKey) 81 } 82 83 func (c *Circuit) Write(msg []byte) (int, error) { 84 // No need to multiplex writes 85 return c.conn.Write(msg) 86 } 87 88 func (c *Circuit) BufferCell(cell []byte, err error) { 89 c.cells <- cell 90 c.errs <- err 91 } 92 93 func (c *Circuit) Read(msg []byte) (int, error) { 94 cell, ok1 := <-c.cells 95 err, ok2 := <-c.errs 96 if !ok1 || !ok2 { 97 return 0, io.EOF 98 } else if err != nil { 99 return 0, err 100 } 101 n := copy(msg, cell) 102 return n, nil 103 } 104 105 func (c *Circuit) Close() error { 106 close(c.cells) 107 return nil 108 } 109 110 func breakMessages(msg []byte, res chan []byte) { 111 body := make([]byte, BODY_SIZE) 112 binary.LittleEndian.PutUint64(body, uint64(len(msg))) 113 bytes := copy(body[LEN_SIZE:], msg) 114 res <- body 115 for bytes < len(msg) { 116 body := make([]byte, BODY_SIZE) 117 bytes += copy(body, msg[bytes:]) 118 res <- body 119 } 120 close(res) 121 } 122 123 // SendMessage divides a message into cells and sends each cell over the network 124 // connection. A message is signaled to the receiver by the first byte of the 125 // first cell. The next few bytes encode the total number of bytes in the 126 // message. 127 func (c *Circuit) SendMessage(msg []byte) error { 128 cell := make([]byte, CellBytes) 129 binary.LittleEndian.PutUint64(cell[ID:], c.id) 130 cell[TYPE] = msgCell 131 132 bodies := make(chan []byte) 133 134 go breakMessages(msg, bodies) 135 for { 136 body, ok := <-bodies 137 if !ok { 138 break 139 } 140 boxed := c.Encrypt(body) 141 copy(cell[BODY:], boxed) 142 if _, err := c.Write(cell); err != nil { 143 return err 144 } 145 } 146 return nil 147 } 148 149 // SendDirective serializes and pads a directive to the length of a cell and 150 // sends it to the peer. A directive is signaled to the receiver by the first 151 // byte of the cell. The next few bytes encode the length of of the serialized 152 // protocol buffer. If the buffer doesn't fit in a cell, then throw an error. 153 func (c *Circuit) SendDirective(d *Directive) (int, error) { 154 cell, err := marshalDirective(c.id, d) 155 if err != nil { 156 return 0, err 157 } 158 return c.Write(cell) 159 } 160 161 // ReceiveMessage reads message cells from the router and assembles them into 162 // a messsage. 163 func (c *Circuit) ReceiveMessage() ([]byte, error) { 164 // Receive cells from router. 165 cell := make([]byte, CellBytes) 166 n, err := c.Read(cell) 167 if err != nil { 168 return nil, err 169 } 170 171 if cell[TYPE] == dirCell { 172 var d Directive 173 if err = unmarshalDirective(cell, &d); err != nil { 174 return nil, err 175 } 176 if *d.Type == DirectiveType_ERROR { 177 return nil, errors.New("router error: " + (*d.Error)) 178 } 179 return nil, errCellType 180 } else if cell[TYPE] != msgCell { 181 return nil, errCellType 182 } 183 184 boxed := cell[BODY:n] 185 if len(boxed) > 0 { 186 body, ok := c.Decrypt(boxed) 187 if !ok { 188 return nil, errors.New("Misauthenticated ciphertext") 189 } 190 191 msgBytes := binary.LittleEndian.Uint64(body) 192 if msgBytes > MaxMsgBytes { 193 return nil, errMsgLength 194 } 195 196 msg := make([]byte, msgBytes) 197 bytes := copy(msg, body[LEN_SIZE:]) 198 199 for uint64(bytes) < msgBytes { 200 tao.ZeroBytes(cell) 201 n, err = c.Read(cell) 202 if err != nil { 203 return nil, err 204 } else if cell[TYPE] != msgCell { 205 return nil, errCellType 206 } 207 boxed := cell[BODY:n] 208 body, ok := c.Decrypt(boxed) 209 if !ok { 210 return nil, errors.New("Misauthenticated ciphertext") 211 } 212 bytes += copy(msg[bytes:], body) 213 } 214 return msg, nil 215 } else { 216 return nil, nil 217 } 218 } 219 220 // ReceiveDirective awaits a reply from the peer and returns the directive 221 // received, e.g. in response to RouterContext.HandleProxy(). If the directive 222 // type is ERROR, return an error. 223 func (c *Circuit) ReceiveDirective(d *Directive) error { 224 cell := make([]byte, CellBytes) 225 _, err := c.Read(cell) 226 if err != nil { 227 return err 228 } 229 230 err = unmarshalDirective(cell, d) 231 if err != nil { 232 return err 233 } 234 235 if *d.Type == DirectiveType_ERROR { 236 return errors.New("router error: " + (*d.Error)) 237 } 238 return nil 239 }