29const size_t MESSAGE_HEADER_LEN = 12;
32const size_t DIGEST_LEN = 128;
33static_assert(DIGEST_LEN <= numeric_limits<uint16_t>::max(),
34 "DIGEST_LEN must fit in a uint16_t");
43digestPreviousMAC(
OutputBuffer& buffer,
const vector<uint8_t>& previous_digest) {
44 if (previous_digest.empty()) {
51 const uint16_t previous_digest_len(previous_digest.size());
53 buffer.
writeData(&previous_digest[0], previous_digest_len);
70 uint16_t rrclass, uint32_t rrttl,
71 uint64_t time_signed, uint16_t fudge, uint16_t error,
72 uint16_t otherlen,
const void* otherdata,
73 bool time_variables_only) {
74 if (!time_variables_only) {
83 if (!time_variables_only) {
113 if (!
data || (data_len < MESSAGE_HEADER_LEN)) {
118 const uint8_t* msgptr =
static_cast<const uint8_t*
>(
data);
121 hdr.writeUint16(qid);
122 msgptr +=
sizeof(uint16_t);
125 hdr.writeData(msgptr, 8);
134 buffer.
writeData(hdr.getData(), hdr.getLength());
135 buffer.
writeData(msgptr, data_len - MESSAGE_HEADER_LEN);
145 error_(
TSIGError::NOERROR()), previous_timesigned_(0),
146 last_sig_dist_(-1), tbs_(1024) {
154 const size_t data_len) {
157 "TSIG sign attempt after verifying a response");
160 if (!
data || (data_len == 0)) {
165 const uint64_t now =
static_cast<uint64_t
>(time(0));
177 TSIG(key_.getAlgorithmName(),
179 qid, error.getCode(), 0, 0)));
180 previous_digest_.clear();
185 if (!key_.getSecCtx().get()) {
191 if (state_ !=
INIT) {
192 digestPreviousMAC(tbs_, previous_digest_);
196 tbs_.writeData(
data, data_len);
200 uint64_t time_signed = now;
201 uint16_t otherlen = 0;
206 time_signed = previous_timesigned_;
214 digestTSIGVariables(tbs_, key_,
218 otherlen, otherlen ? otherdata.
getData() : 0,
226 key_.getSecCtx().sign(gtbs, gsign);
233 TSIG(key_.getAlgorithmName(),
236 qid, error.getCode(), otherlen,
237 otherlen ? otherdata.
getData() : 0)));
239 if (state_ ==
INIT) {
249 const void*
const data,
const size_t data_len) {
252 "TSIG verify attempt after sending a response");
261 if (state_ ==
INIT) {
276 if ((last_sig_dist_ >= 0) && (last_sig_dist_ < 99)) {
295 if (data_len < MESSAGE_HEADER_LEN + record->getLength()) {
297 "TSIG verify: data length is invalid: " << data_len);
303 if (!key_.getSecCtx().get()) {
316 if ((key_.getKeyName() != record->
getName()) ||
317 (key_.getAlgorithmName() != tsig_rdata.
getAlgorithm())) {
328 const uint64_t now =
static_cast<uint64_t
>(time(0));
331 if (state_ ==
INIT) {
332 const uint8_t* digest =
333 static_cast<const uint8_t*
>(tsig_rdata.
getMAC());
335 previous_digest_.assign(digest,
354 return (postVerifyUpdate(error));
359 if (state_ !=
INIT) {
360 digestPreviousMAC(tbs_, previous_digest_);
378 digestTSIGVariables(tbs_, key_,
393 key_.getSecCtx().verify(gtbv, gsign);
395 const uint8_t* digest =
396 static_cast<const uint8_t*
>(tsig_rdata.
getMAC());
397 previous_digest_.assign(digest, digest + tsig_rdata.
getMACSize());
408 if (last_sig_dist_ == -1) {
411 return (last_sig_dist_ == 0);
440 size_t digest_len = DIGEST_LEN;
447 size_t other_len = 0;
452 return (26 + key_.getKeyName().getLength() +
453 key_.getAlgorithmName().getLength() +
454 digest_len + other_len);
460 digestPreviousMAC(tbs_, previous_digest_);
461 previous_digest_.clear();
463 tbs_.writeData(
data, len);
virtual const char * what() const
Returns a C-style character string of the cause of the exception.
A generic exception that is thrown if a parameter given to a method or function is considered invalid...
A generic exception that is thrown if a parameter given to a method would refer to or modify out-of-r...
A generic exception that is thrown when an unexpected error condition occurs.
void toWire(AbstractMessageRenderer &renderer) const
Render the Name in the wire format with compression.
An exception that is thrown for logic errors identified in TSIG sign/verify operations.
@ RECEIVED_REQUEST
Server received a signed request.
@ SENT_REQUEST
Client sent a signed request, waiting response.
@ SENT_RESPONSE
Server sent a signed response.
@ VERIFIED_RESPONSE
Client successfully verified a response.
static const uint16_t DEFAULT_FUDGE
The recommended fudge value (in seconds) by RFC2845.
TSIGContext(const TSIGKey &key)
Constructor from a TSIG key.
static const TSIGError & BAD_SIG()
A constant TSIG error object for the BADSIG code (see TSIGError::BAD_SIG_CODE).
static const TSIGError & BAD_KEY()
A constant TSIG error object for the BADKEY code (see TSIGError::BAD_KEY_CODE).
static const TSIGError & BAD_TIME()
A constant TSIG error object for the BADTIME code (see TSIGError::BAD_TIME_CODE).
static const TSIGError & NOERROR()
A constant TSIG error object derived from Rcode::NOERROR()
static const TSIGError & FORMERR()
A constant TSIG error object derived from Rcode::FORMERR()
const Name & getAlgorithmName() const
Return the algorithm name.
const Name & getKeyName() const
Getter Methods.
static const RRClass & getClass()
Return the RR class of TSIG.
static const uint32_t TSIG_TTL
The TTL value to be used in TSIG RRs.
size_t getLength() const
Return the length of the TSIG record.
const Name & getName() const
Return the owner name of the TSIG RR, which is the TSIG key name.
const rdata::any::TSIG & getRdata() const
Return the RDATA of the TSIG RR.
rdata::TSIG class represents the TSIG RDATA as defined in RFC2845.
uint16_t getOriginalID() const
Return the value of the Original ID field.
uint16_t getError() const
Return the value of the Error field.
const Name & getAlgorithm() const
Return the algorithm name.
uint16_t getOtherLen() const
Return the value of the Other Len field.
const void * getOtherData() const
Return the value of the Other Data field.
const void * getMAC() const
Return the value of the MAC field.
uint16_t getFudge() const
Return the value of the Fudge field.
uint16_t getMACSize() const
Return the value of the MAC Size field.
uint64_t getTimeSigned() const
Return the value of the Time Signed field.
std::vector< uint8_t > getContent() const
Get the content as a vector.
void * getValue()
Get the value.
size_t getLength() const
Get the length.
virtual bool lastHadSignature() const override
Check whether the last verified message was signed.
virtual ~GssTsigContext()
Destructor.
virtual dns::ConstTSIGRecordPtr sign(const uint16_t qid, const void *const data, const size_t data_len) override
Sign a DNS message.
virtual size_t getTSIGLength() const override
Return the expected length of TSIG RR after sign().
void update(const void *const data, size_t len)
Update internal MAC state by more data.
virtual dns::TSIGError verify(const dns::TSIGRecord *const record, const void *const data, const size_t data_len) override
a DNS message.
GssTsigContext(GssTsigKey &key)
Constructor.
GSS-TSIG extension of the D2 TSIG key class.
The OutputBuffer class is a buffer abstraction for manipulating mutable data.
void writeUint16(uint16_t data)
Write an unsigned 16-bit integer in host byte order into the buffer in network byte order.
void writeData(const void *data, size_t len)
Copy an arbitrary length of data into the buffer.
void writeUint32(uint32_t data)
Write an unsigned 32-bit integer in host byte order into the buffer in network byte order.
const uint8_t * getData() const
Return a pointer to the head of the data stored in the buffer.
#define isc_throw(type, stream)
A shortcut macro to insert known values into exception arguments.
Implements a TSIGContext derived class which can be used as the value of TSIGContext pointers so with...
#define LOG_INFO(LOGGER, MESSAGE)
Macro to conveniently test info output and log it.
#define LOG_DEBUG(LOGGER, LEVEL, MESSAGE)
Macro to conveniently test debug output and log it.
boost::shared_ptr< const TSIGRecord > ConstTSIGRecordPtr
A pointer-like type pointing to an immutable TSIGRecord object.
const isc::log::MessageID GSS_TSIG_VERIFIED
const isc::log::MessageID GSS_TSIG_VERIFY_FAILED
isc::log::Logger gss_tsig_logger("gss-tsig-hooks")
const int DBGLVL_TRACE_BASIC
Trace basic operations.
uint16_t readUint16(void const *const buffer, size_t const length)
uint16_t wrapper over readUint.
Defines the logger used by the top-level component of kea-lfc.