func newHeader( sender, recipient *uid.Message, recipientTempHash string, senderSessionPub, nextSenderSessionPub, nextRecipientSessionPubSeen *uid.KeyEntry, nymAddress string, senderSessionCount, senderMessageCount uint64, senderLastKeychainHash string, rand io.Reader, statusCode StatusCode, ) (*header, error) { if len(senderLastKeychainHash) != hashchain.EntryBase64Len { return nil, log.Errorf("msg: last hashchain entry '%s' does not have base64 length %d (but %d)", senderLastKeychainHash, hashchain.EntryBase64Len, len(senderLastKeychainHash)) } h := &header{ Ciphersuite: uid.DefaultCiphersuite, // at the moment we only support one ciphersuite RecipientPubHash: recipient.PubHash(), RecipientTempHash: recipientTempHash, SenderIdentity: sender.Identity(), SenderSessionPub: *senderSessionPub, SenderIdentityPubHash: sender.PubHash(), SenderIdentityPub: *sender.PubKey(), NextSenderSessionPub: nextSenderSessionPub, NextRecipientSessionPubSeen: nextRecipientSessionPubSeen, NymAddress: nymAddress, MaxDelay: 0, // TODO SenderSessionCount: senderSessionCount, SenderMessageCount: senderMessageCount, SenderUID: string(sender.JSON()), SenderLastKeychainHash: senderLastKeychainHash, Status: statusCode, Padding: "", // is set below } // calculate padding length padLen := wiggleRoom // pad sender identity if len(h.SenderIdentity) > identity.MaxLen { return nil, log.Error("msg: sender identity is too long") } padLen += identity.MaxLen - len(h.SenderIdentity) // pad nextSenderSessionPub if nextSenderSessionPub == nil { padLen += length.KeyEntryECDHE25519 - length.Nil } // pad nextRecipientSessionPubSeen if nextRecipientSessionPubSeen == nil { padLen += length.KeyEntryECDHE25519 - length.Nil } // pad nym address if len(h.NymAddress) > length.MaxNymAddress { return nil, log.Error("msg: nym address is too long") } padLen += length.MaxNymAddress - len(h.NymAddress) // pad integers padLen += 20 - digits.Count(h.MaxDelay) padLen += 20 - digits.Count(h.SenderSessionCount) padLen += 20 - digits.Count(h.SenderMessageCount) // pad sender UIDMessage if len(h.SenderUID) > length.MaxUIDMessage { return nil, log.Error("msg: sender UIDMesssage is too long") } padLen += length.MaxUIDMessage - len(h.SenderUID) // generate padding randLen := padLen/2 + padLen%2 pad, err := padding.Generate(randLen, cipher.RandReader) if err != nil { return nil, err } // set padding p := hex.EncodeToString(pad) if padLen%2 == 1 { p = p[:len(p)-1] } h.Padding = p return h, nil }