PullMsgResult ProduceReady(ref Msg msg) { int metadataLength = BasicPropertiesLength; Span <byte> readyNonce = stackalloc byte[Curve25519XSalsa20Poly1305.NonceLength]; byte[] readyPlaintext = new byte[metadataLength]; // Create Box [metadata](S'->C') AddBasicProperties(readyPlaintext); ReadyNoncePrefix.CopyTo(readyNonce); NetworkOrderBitsConverter.PutUInt64(m_nonce, readyNonce.Slice(16)); msg.InitPool(14 + Curve25519XSalsa20Poly1305.TagLength + metadataLength); var readyBox = msg.Slice(14); Assumes.NotNull(m_box); m_box.Encrypt(readyBox, readyPlaintext, readyNonce); Array.Clear(readyPlaintext, 0, readyPlaintext.Length); Span <byte> ready = msg; ReadyLiteral.CopyTo(ready); // Short nonce, prefixed by "CurveZMQREADY---" readyNonce.Slice(16).CopyTo(ready.Slice(6)); m_nonce++; return(0); }
PullMsgResult ProduceInitiate(ref Msg msg) { int metadataLength = BasicPropertiesLength; byte[] metadataPlaintext = new byte[metadataLength]; AddBasicProperties(metadataPlaintext); msg.InitPool(113 + 128 + metadataLength + Curve25519XSalsa20Poly1305.TagLength); Span <byte> vouchNonce = stackalloc byte[Curve25519XSalsa20Poly1305.NonceLength]; Span <byte> vouchPlaintext = stackalloc byte[64]; Span <byte> vouchBox = stackalloc byte[Curve25519XSalsa20Poly1305.TagLength + 64]; // Create vouch = Box [C',S](C->S') m_cnPublicKey.CopyTo(vouchPlaintext); m_serverKey.CopyTo(vouchPlaintext.Slice(32)); VouchNoncePrefix.CopyTo(vouchNonce); using var rng = RandomNumberGenerator.Create(); #if NETSTANDARD2_1 rng.GetBytes(vouchNonce.Slice(8)); #else byte[] temp = new byte[16]; rng.GetBytes(temp); temp.CopyTo(vouchNonce.Slice(8)); #endif using var box = new Curve25519XSalsa20Poly1305(m_secretKey, m_cnServerKey); box.Encrypt(vouchBox, vouchPlaintext, vouchNonce); Span <byte> initiate = msg; Span <byte> initiateNonce = stackalloc byte[Curve25519XSalsa20Poly1305.NonceLength]; Span <byte> initiatePlaintext = new byte[128 + metadataLength]; Span <byte> initiateBox = initiate.Slice(113); // Create Box [C + vouch + metadata](C'->S') m_publicKey.CopyTo(initiatePlaintext); vouchNonce.Slice(8).CopyTo(initiatePlaintext.Slice(32)); vouchBox.CopyTo(initiatePlaintext.Slice(48)); metadataPlaintext.CopyTo(initiatePlaintext.Slice(48 + 80)); Array.Clear(metadataPlaintext, 0, metadataPlaintext.Length); InitiatieNoncePrefix.CopyTo(initiateNonce); NetworkOrderBitsConverter.PutUInt64(m_nonce, initiateNonce.Slice(16)); using var box2 = new Curve25519XSalsa20Poly1305(m_cnSecretKey, m_cnServerKey); box2.Encrypt(initiateBox, initiatePlaintext, initiateNonce); InitiateLiteral.CopyTo(initiate); // Cookie provided by the server in the WELCOME command m_cnCookie.CopyTo(initiate.Slice(9, 96)); // Short nonce, prefixed by "CurveZMQINITIATE" initiateNonce.Slice(16).CopyTo(initiate.Slice(105)); m_nonce++; return(PullMsgResult.Ok); }
public override PullMsgResult Encode(ref Msg msg) { Span <byte> messageNonce = stackalloc byte[Curve25519XSalsa20Poly1305.NonceLength]; m_encodeNoncePrefix.CopyTo(messageNonce); NetworkOrderBitsConverter.PutUInt64(m_nonce, messageNonce.Slice(16)); byte flags = 0; if (msg.HasMore) { flags |= 0x01; } if (msg.HasCommand) { flags |= 0x02; } Msg plaintext = new Msg(); plaintext.InitPool(msg.Size + 1); plaintext[0] = flags; msg.CopyTo(plaintext.Slice(1)); msg.Close(); msg.InitPool(16 + Curve25519XSalsa20Poly1305.TagLength + plaintext.Size); Assumes.NotNull(m_box); m_box.Encrypt(msg.Slice(16), plaintext, messageNonce); plaintext.Close(); MessageLiteral.CopyTo(msg); NetworkOrderBitsConverter.PutUInt64(m_nonce, msg.Slice(8)); m_nonce++; return(PullMsgResult.Ok); }
PullMsgResult ProduceHello(ref Msg msg) { msg.InitPool(200); Span <byte> helloNonce = stackalloc byte[Curve25519XSalsa20Poly1305.NonceLength]; Span <byte> helloPlaintext = stackalloc byte[64]; Span <byte> helloBox = msg.Slice(120); // Prepare the full nonce HelloNoncePrefix.CopyTo(helloNonce); NetworkOrderBitsConverter.PutUInt64(m_nonce, helloNonce.Slice(16)); // Create Box [64 * %x0](C'->S) using var box = new Curve25519XSalsa20Poly1305(m_cnSecretKey, m_serverKey); box.Encrypt(helloBox, helloPlaintext, helloNonce); Span <byte> hello = msg; HelloLiteral.CopyTo(hello); // CurveZMQ major and minor version numbers hello[6] = 1; hello[7] = 0; // 8-80 are left zeros for anti-amplification padding // Client public connection key m_cnPublicKey.CopyTo(hello.Slice(80)); // Short nonce, prefixed by "CurveZMQHELLO---" helloNonce.Slice(16).CopyTo(hello.Slice(112)); m_nonce++; return(PullMsgResult.Ok); }