Merge remote-tracking branch 'origin/upstream/master'
diff --git a/BUILD.gn b/BUILD.gn
index 7793f40..fe40d68 100644
--- a/BUILD.gn
+++ b/BUILD.gn
@@ -20,12 +20,8 @@
 executable("simple_server") {
   sources = [
     "clock_linux.cc",
-    "protocol.cc",
-    "server.cc",
-    "simple_server.cc",
     "simple_server_main.cc",
     "sys_time.cc",
-    "udp_processor.cc",
   ]
   defines = [
     "USE_GLOG",
@@ -33,6 +29,28 @@
   ]
   include_dirs = [ "." ]
   deps = [
+    ":simple_server_lib",
+    "//third_party/boringssl",
+    "//third_party/glog",
+  ]
+}
+
+static_library("simple_server_lib") {
+  sources = [
+    "protocol.cc",
+    "server.cc",
+    "simple_server.cc",
+    "simple_server.h",
+    "udp_processor.cc",
+    "udp_processor.h",
+  ]
+  defines = [
+    "USE_GLOG",
+    "ROUGHTIME_OPEN_SOURCE",
+  ]
+  include_dirs = [ "." ]
+  public_configs = [ ":client_config" ]
+  deps = [
     "//third_party/boringssl",
     "//third_party/glog",
   ]
diff --git a/client.h b/client.h
index fbe22ac..b1dd3de 100644
--- a/client.h
+++ b/client.h
@@ -30,7 +30,7 @@
 // and a certificate signed with a private key that matches |root_public_key|.
 bool ParseResponse(uint64_t *out_time, uint32_t *out_radius,
                    std::string *out_error,
-                   const uint8_t root_public_key[ED25519_PUBLIC_KEY_LEN],
+                   const uint8_t root_public_key[kPublicKeyLength],
                    const uint8_t *response_bytes, size_t response_len,
                    const uint8_t nonce[kNonceLength]);
 
diff --git a/go/protocol/protocol.go b/go/protocol/protocol.go
index ad8f7dd..9d409ef 100644
--- a/go/protocol/protocol.go
+++ b/go/protocol/protocol.go
@@ -89,7 +89,7 @@
 
 	var payloadSum uint64
 	for _, payload := range msg {
-		if len(payload) % 4 != 0 {
+		if len(payload)%4 != 0 {
 			return nil, errors.New("encode: length of value is not a multiple of four")
 		}
 		payloadSum += uint64(len(payload))
@@ -139,7 +139,7 @@
 	if len(bytes) < 4 {
 		return nil, errors.New("decode: message too short to be valid")
 	}
-	if len(bytes) % 4 != 0 {
+	if len(bytes)%4 != 0 {
 		return nil, errors.New("decode: message is not a multiple of four bytes")
 	}
 
@@ -149,13 +149,15 @@
 		return make(map[uint32][]byte), nil
 	}
 
-	if uint64(len(bytes)) < 4*((numTags-1)+numTags) {
+	minLen := 4 * (1 + (numTags - 1) + numTags)
+
+	if uint64(len(bytes)) < minLen {
 		return nil, errors.New("decode: message too short to be valid")
 	}
 
 	offsets := bytes[4:]
 	tags := bytes[4*(1+numTags-1):]
-	payloads := bytes[4*(1+(numTags-1)+numTags):]
+	payloads := bytes[minLen:]
 
 	if len(payloads) > math.MaxInt32 {
 		return nil, errors.New("decode: message too large")
diff --git a/protocol.cc b/protocol.cc
index 751f1cc..744dc04 100644
--- a/protocol.cc
+++ b/protocol.cc
@@ -24,6 +24,7 @@
 #include <string.h>
 
 #include <openssl/sha.h>
+#include <openssl/curve25519.h>
 
 #include "logging.h"
 
@@ -32,6 +33,15 @@
 static_assert(BYTE_ORDER == LITTLE_ENDIAN,
               "This code assumes little-endian processors");
 
+// The OpenSSL constants are kept out of the headers to allow consumers to
+// avoid needing OpenSSL's at build time, but the values should still match.
+static_assert(kPrivateKeyLength == ED25519_PRIVATE_KEY_LEN,
+              "Private key length mismatch");
+static_assert(kPublicKeyLength == ED25519_PUBLIC_KEY_LEN,
+              "Public key length mismatch");
+static_assert(kSignatureLength == ED25519_SIGNATURE_LEN,
+              "Signature length mismatch");
+
 static void advance(const uint8_t **ptr, size_t *len, size_t bytes) {
   *ptr += bytes;
   *len -= bytes;
diff --git a/protocol.h b/protocol.h
index a64932f..c32919f 100644
--- a/protocol.h
+++ b/protocol.h
@@ -18,8 +18,6 @@
 #include <stdint.h>
 #include <string.h>
 
-#include <openssl/curve25519.h>
-
 namespace roughtime {
 
 // Minimum size of a time request.  Requests must be padded to larger than their
@@ -32,6 +30,12 @@
 
 constexpr size_t kRadiusSize = 4;  // Size of the server's uncertainty.
 
+constexpr size_t kPrivateKeyLength = 64; // Size of the server's private key.
+
+constexpr size_t kPublicKeyLength = 32; // Size of the server's public key.
+
+constexpr size_t kSignatureLength = 64; // Size of server signatures.
+
 typedef uint32_t tag_t;
 
 // rough_time_t is the type of a time stamp. Time is UTC and is given as
diff --git a/server.h b/server.h
index 6a119b5..cf3d84d 100644
--- a/server.h
+++ b/server.h
@@ -18,7 +18,6 @@
 #include <memory>
 #include <utility>
 
-
 #include "protocol.h"
 #include "time_source.h"
 
@@ -27,12 +26,12 @@
 // kToBeSignedCertSize is the size of the signed portion (DELE) of a
 // certificate.  Its tags are (PUBK, MINT, MAXT).
 constexpr size_t kToBeSignedCertSize = MessageHeaderLen(3) +
-                                       ED25519_PUBLIC_KEY_LEN + kTimestampSize +
+                                       kPublicKeyLength + kTimestampSize +
                                        kTimestampSize;
 
 // kCertSize is the size of the entire certificate.  Its tags are (DELE, SIG).
 constexpr size_t kCertSize =
-    MessageHeaderLen(2) + ED25519_SIGNATURE_LEN + kToBeSignedCertSize;
+    MessageHeaderLen(2) + kSignatureLength + kToBeSignedCertSize;
 
 // CreateCertificate signs the supplied |public_key| using |root_private_key|,
 // and sets |out_cert| to a certificate containing the public key, the
@@ -40,14 +39,14 @@
 // otherwise false.
 // TODO(mab): Find better home for this, likely in an offline tool.
 bool CreateCertificate(uint8_t out_cert[kCertSize],
-                       const uint8_t root_private_key[ED25519_PRIVATE_KEY_LEN],
+                       const uint8_t root_private_key[kPrivateKeyLength],
                        rough_time_t start_time, rough_time_t end_time,
-                       const uint8_t public_key[ED25519_PUBLIC_KEY_LEN]);
+                       const uint8_t public_key[kPublicKeyLength]);
 
 // Identity is a server's private key and certificate.  (The certificate is the
 // server's public key signed by an offline private master key.)
 struct Identity {
-  uint8_t private_key[ED25519_PRIVATE_KEY_LEN];
+  uint8_t private_key[kPrivateKeyLength];
   uint8_t certificate[kCertSize];
 };
 
@@ -118,7 +117,7 @@
 
 // kMaxResponseSize is the size of the largest possible server response.
 constexpr size_t kMaxResponseSize =
-    MessageHeaderLen(5) + kCertSize + kToBeSignedSize + ED25519_SIGNATURE_LEN +
+    MessageHeaderLen(5) + kCertSize + kToBeSignedSize + kSignatureLength +
     (kBatchSizeLog2 * kNonceLength) + sizeof(uint32_t) /* index */;
 
 class Server {
@@ -163,7 +162,7 @@
   uint8_t* const to_be_signed_;
 
   // Signature is the ED25519 signature over |to_be_signed_with_context_|.
-  uint8_t signature_[ED25519_SIGNATURE_LEN];
+  uint8_t signature_[kSignatureLength];
 };
 
 // BrokenReplyGenerator is an interface for generating replies that are broken
diff --git a/simple_server.h b/simple_server.h
index 30f09f7..4d9284e 100644
--- a/simple_server.h
+++ b/simple_server.h
@@ -47,7 +47,7 @@
   // MakeIdentity creates a dummy server certificate that is valid for the
   // given time range.
   static std::unique_ptr<Identity> MakeIdentity(
-      const uint8_t root_private_key[ED25519_PRIVATE_KEY_LEN],
+      const uint8_t root_private_key[kPrivateKeyLength],
       rough_time_t mint, rough_time_t maxt);
 
  private:
diff --git a/simple_server_main.cc b/simple_server_main.cc
index c008513..225859a 100644
--- a/simple_server_main.cc
+++ b/simple_server_main.cc
@@ -26,7 +26,7 @@
 
 // root_private_key is an Ed25519 private key used by simple_server. The
 // private part consists of all zeros and so is only for use in this example.
-constexpr uint8_t root_private_key[ED25519_PRIVATE_KEY_LEN] = {
+constexpr uint8_t root_private_key[roughtime::kPrivateKeyLength] = {
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
     0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3b, 0x6a, 0x27, 0xbc,
diff --git a/udp_processor.cc b/udp_processor.cc
index d7a098a..5a82a04 100644
--- a/udp_processor.cc
+++ b/udp_processor.cc
@@ -112,7 +112,9 @@
 
 #if defined(__MACH__)
 static const unsigned MSG_WAITFORONE = 0;
+#endif
 
+#if defined(__MACH__) || defined(__Fuchsia__)
 static int recvmmsg(int fd, struct mmsghdr *msgvec, unsigned vlen,
                     unsigned flags, struct timespec *timeout) {
   ssize_t r = recvmsg(fd, &msgvec->msg_hdr, 0);
@@ -125,7 +127,7 @@
 }
 
 int sendmmsg(int fd, struct mmsghdr *msgvec, unsigned vlen, unsigned flags) {
-  ROUGHTIME_CHECK_EQ(1, vlen);
+  ROUGHTIME_CHECK_EQ((unsigned) 1, vlen);
   ssize_t r = sendmsg(fd, &msgvec->msg_hdr, 0);
   if (r < 0) {
     return r;
diff --git a/udp_processor.h b/udp_processor.h
index d051348..2f6d6e4 100644
--- a/udp_processor.h
+++ b/udp_processor.h
@@ -25,7 +25,7 @@
 
 namespace roughtime {
 
-#if defined(__MACH__)
+#if defined(__MACH__) || defined(__Fuchsia__)
 struct mmsghdr {
   uint8_t *iov_base;
   size_t msg_len;