Verify the signature on the given token.
| 104 | |
| 105 | // Verify the signature on the given token. |
| 106 | TokenVerificationResult TokenVerifier::VerifyTokenSignature( |
| 107 | const SignedTokenPB& signed_token, TokenPB* token) const { |
| 108 | if (!signed_token.has_signature() || |
| 109 | !signed_token.has_signing_key_seq_num() || |
| 110 | !signed_token.has_token_data()) { |
| 111 | return TokenVerificationResult::INVALID_TOKEN; |
| 112 | } |
| 113 | |
| 114 | if (!token->ParseFromString(signed_token.token_data()) || |
| 115 | !token->has_expire_unix_epoch_seconds()) { |
| 116 | return TokenVerificationResult::INVALID_TOKEN; |
| 117 | } |
| 118 | |
| 119 | int64_t now = WallTime_Now(); |
| 120 | if (token->expire_unix_epoch_seconds() < now) { |
| 121 | return TokenVerificationResult::EXPIRED_TOKEN; |
| 122 | } |
| 123 | |
| 124 | for (auto flag : token->incompatible_features()) { |
| 125 | if (!TokenPB::Feature_IsValid(flag)) { |
| 126 | KLOG_EVERY_N_SECS(WARNING, 60) << "received token with unknown feature; " |
| 127 | "server needs to be updated"; |
| 128 | return TokenVerificationResult::INCOMPATIBLE_FEATURE; |
| 129 | } |
| 130 | } |
| 131 | |
| 132 | { |
| 133 | shared_lock<RWMutex> l(lock_); |
| 134 | auto* tsk = FindPointeeOrNull(keys_by_seq_, signed_token.signing_key_seq_num()); |
| 135 | if (!tsk) { |
| 136 | return TokenVerificationResult::UNKNOWN_SIGNING_KEY; |
| 137 | } |
| 138 | if (tsk->pb().expire_unix_epoch_seconds() < now) { |
| 139 | return TokenVerificationResult::EXPIRED_SIGNING_KEY; |
| 140 | } |
| 141 | if (!tsk->VerifySignature(signed_token)) { |
| 142 | return TokenVerificationResult::INVALID_SIGNATURE; |
| 143 | } |
| 144 | } |
| 145 | |
| 146 | return TokenVerificationResult::VALID; |
| 147 | } |
| 148 | |
| 149 | const char* TokenVerificationResultToString(TokenVerificationResult r) { |
| 150 | switch (r) { |