Added more documentation and some bug fixes in verification process

This commit is contained in:
Arun M 2017-12-27 12:18:44 +05:30
parent 3d9e15b5c8
commit e42720a446
6 changed files with 91 additions and 10 deletions

View file

@ -17,6 +17,7 @@ enum class AlgorithmErrc
/** /**
* Algorithm error conditions * Algorithm error conditions
* TODO: Remove it or use it!
*/ */
enum class AlgorithmFailureSource enum class AlgorithmFailureSource
{ {
@ -27,18 +28,29 @@ enum class AlgorithmFailureSource
*/ */
enum class DecodeErrc enum class DecodeErrc
{ {
// No algorithms provided in decode API
EmptyAlgoList = 1, EmptyAlgoList = 1,
// The JWT signature has incorrect format
SignatureFormatError, SignatureFormatError,
// The JSON library failed to parse
JsonParseError, JsonParseError,
// Algorithm field in header is missing
AlgHeaderMiss, AlgHeaderMiss,
// Type field in header is missing
TypHeaderMiss, TypHeaderMiss,
// Unexpected type field value
TypMismatch, TypMismatch,
// Found duplicate claims
DuplClaims, DuplClaims,
// Key/Secret not passed as decode argument
KeyNotPresent, KeyNotPresent,
// Key/secret passed as argument for NONE algorithm.
// Not a hard error.
KeyNotRequiredForNoneAlg, KeyNotRequiredForNoneAlg,
}; };
/** /**
* Errors handled during verification process.
*/ */
enum class VerificationErrc enum class VerificationErrc
{ {

View file

@ -7,6 +7,8 @@
namespace jwt { namespace jwt {
/** /**
* Exception for allocation related failures in the
* OpenSSL C APIs.
*/ */
class MemoryAllocationException final: public std::bad_alloc class MemoryAllocationException final: public std::bad_alloc
{ {
@ -31,6 +33,8 @@ private:
}; };
/** /**
* Exception thrown for failures in OpenSSL
* APIs while signing.
*/ */
class SigningError : public std::runtime_error class SigningError : public std::runtime_error
{ {
@ -44,6 +48,7 @@ public:
}; };
/** /**
* Exception thrown for decode related errors.
*/ */
class DecodeError: public std::runtime_error class DecodeError: public std::runtime_error
{ {
@ -57,6 +62,8 @@ public:
}; };
/** /**
* A derived decode error for signature format
* error.
*/ */
class SignatureFormatError final : public DecodeError class SignatureFormatError final : public DecodeError
{ {
@ -70,6 +77,8 @@ public:
}; };
/** /**
* A derived decode error for Key argument not present
* error. Only thrown if the algorithm set is not NONE.
*/ */
class KeyNotPresentError final : public DecodeError class KeyNotPresentError final : public DecodeError
{ {
@ -84,6 +93,9 @@ public:
/** /**
* Base class exception for all kinds of verification errors.
* Verification errors are thrown only when the verify
* decode parameter is set to true.
*/ */
class VerificationError : public std::runtime_error class VerificationError : public std::runtime_error
{ {
@ -97,6 +109,9 @@ public:
}; };
/** /**
* Derived from VerificationError.
* Thrown when the algorithm decoded in the header
* is incorrect.
*/ */
class InvalidAlgorithmError final: public VerificationError class InvalidAlgorithmError final: public VerificationError
{ {
@ -110,6 +125,9 @@ public:
}; };
/** /**
* Derived from VerificationError.
* Thrown when the token is expired at the
* time of decoding.
*/ */
class TokenExpiredError final: public VerificationError class TokenExpiredError final: public VerificationError
{ {
@ -123,6 +141,9 @@ public:
}; };
/** /**
* Derived from VerificationError.
* Thrown when the issuer claim does not match
* with the one provided as part of decode argument.
*/ */
class InvalidIssuerError final: public VerificationError class InvalidIssuerError final: public VerificationError
{ {
@ -136,6 +157,9 @@ public:
}; };
/** /**
* Derived from VerificationError.
* Thrown when the audience claim does not match
* with the one provided as part of decode argument.
*/ */
class InvalidAudienceError final: public VerificationError class InvalidAudienceError final: public VerificationError
{ {
@ -149,6 +173,9 @@ public:
}; };
/** /**
* Derived from VerificationError.
* Thrown when the token is decoded at a time before
* as specified in the `nbf` claim.
*/ */
class ImmatureSignatureError final: public VerificationError class ImmatureSignatureError final: public VerificationError
{ {
@ -162,6 +189,8 @@ public:
}; };
/** /**
* Derived from VerificationError.
* Thrown when the signature does not match in the verification process.
*/ */
class InvalidSignatureError final: public VerificationError class InvalidSignatureError final: public VerificationError
{ {

View file

@ -398,26 +398,36 @@ std::error_code jwt_object::verify(
} }
//Check for issuer //Check for issuer
if (dparams.has_issuer && if (dparams.has_issuer)
has_claim(registered_claims::issuer))
{ {
jwt::string_view p_issuer = payload() if (has_claim(registered_claims::issuer))
.get_claim_value<std::string>(registered_claims::issuer); {
jwt::string_view p_issuer = payload()
.get_claim_value<std::string>(registered_claims::issuer);
if (p_issuer.data() != dparams.issuer) { if (p_issuer.data() != dparams.issuer) {
ec = VerificationErrc::InvalidIssuer;
return ec;
}
} else {
ec = VerificationErrc::InvalidIssuer; ec = VerificationErrc::InvalidIssuer;
return ec; return ec;
} }
} }
//Check for audience //Check for audience
if (dparams.has_aud && if (dparams.has_aud)
has_claim(registered_claims::audience))
{ {
jwt::string_view p_aud = payload() if (has_claim(registered_claims::audience))
.get_claim_value<std::string>(registered_claims::audience); {
jwt::string_view p_aud = payload()
.get_claim_value<std::string>(registered_claims::audience);
if (p_aud.data() != dparams.aud) { if (p_aud.data() != dparams.aud) {
ec = VerificationErrc::InvalidAudience;
return ec;
}
} else {
ec = VerificationErrc::InvalidAudience; ec = VerificationErrc::InvalidAudience;
return ec; return ec;
} }

View file

@ -749,6 +749,20 @@ public: // 'tors
* Takes a variadic set of parameters. * Takes a variadic set of parameters.
* Each type must satisfy the * Each type must satisfy the
* `ParameterConcept` concept. * `ParameterConcept` concept.
*
* The parameters that can be passed:
* 1. payload : Can pass a initializer list of pairs or any associative
* containers which models `MappingConcept` (see `meta::is_mapping_concept`)
* to populate claims. Use `add_claim` for more controlled additions.
*
* 2. secret : The secret to be used for generating and verification
* of JWT signature. Not required for NONE algorithm.
*
* 3. algorithm : The algorithm to be used for signing and decoding.
*
* 4. headers : Can pass a initializer list of pairs or any associative
* containers which models `MappingConcept` (see `meta::is_mapping_concept`)
* to populate header. Not much use.
*/ */
template <typename... Args> template <typename... Args>
jwt_object(Args&&... args); jwt_object(Args&&... args);
@ -1008,6 +1022,22 @@ private: // Data Members
* This version reports error back using `std::error_code`. * This version reports error back using `std::error_code`.
* *
* NOTE: Memory allocation exceptions are not caught. * NOTE: Memory allocation exceptions are not caught.
*
* Optional parameters that can be passed:
* 1. verify : A boolean flag to indicate whether
* the signature should be verified or not.
*
* 2. leeway : Number of seconds that can be added (in case of exp)
* or subtracted (in case of nbf) to be more lenient.
*
* 3. algorithms : Takes in a sequence of algorithms which the client
* expects the signature to be decoded with.
*
* 4. aud : The audience the client expects to be in the claim.
* NOTE: It is case-sensitive.
*
* 5. issuer: The issuer the client expects to be in the claim.
* NOTE: It is case-sensitive
*/ */
template <typename SequenceT, typename... Args> template <typename SequenceT, typename... Args>
jwt_object decode(const string_view enc_str, jwt_object decode(const string_view enc_str,

Binary file not shown.

Binary file not shown.