예제 #1
0
    def compute_mac_and_encode_with_kid(self, raw_jwt: _raw_jwt.RawJwt,
                                        kid: Optional[Text]) -> Text:
        """Computes a MAC and encodes the token.

    Args:
      raw_jwt: The RawJwt token to be MACed and encoded.
      kid: Optional "kid" header value. It is set by the wrapper for keys with
        output prefix TINK, and it is None for output prefix RAW.

    Returns:
      The MACed token encoded in the JWS compact serialization format.
    Raises:
      tink.TinkError if the operation fails.
    """
        if raw_jwt.has_type_header():
            type_header = raw_jwt.type_header()
        else:
            type_header = None
        if self._custom_kid is not None:
            if kid is not None:
                raise _jwt_error.JwtInvalidError(
                    'custom_kid must not be set for keys with output prefix type TINK'
                )
            kid = self._custom_kid
        unsigned = _jwt_format.create_unsigned_compact(self._algorithm,
                                                       type_header, kid,
                                                       raw_jwt.json_payload())
        return _jwt_format.create_signed_compact(unsigned,
                                                 self._compute_mac(unsigned))
예제 #2
0
def create_unsigned_compact(algorithm: str, kid: Optional[str],
                            raw_jwt: _raw_jwt.RawJwt) -> bytes:
  if raw_jwt.has_type_header():
    header = create_header(algorithm, raw_jwt.type_header(), kid)
  else:
    header = create_header(algorithm, None, kid)
  return header + b'.' + encode_payload(raw_jwt.json_payload())
예제 #3
0
 def sign_and_encode_with_kid(self, token: _raw_jwt.RawJwt,
                              kid: Optional[Text]) -> Text:
     """Computes a signature and encodes the token."""
     type_header = token.type_header() if token.has_type_header() else None
     # TODO(juerg): Add support for custom_kid.
     unsigned = _jwt_format.create_unsigned_compact(self._algorithm,
                                                    type_header, kid,
                                                    token.json_payload())
     return _jwt_format.create_signed_compact(unsigned,
                                              self._sign(unsigned))
예제 #4
0
 def compute_mac_and_encode(self, raw_jwt: _raw_jwt.RawJwt) -> Text:
     """Computes a MAC and encodes the token."""
     if raw_jwt.has_type_header():
         type_header = raw_jwt.type_header()
     else:
         type_header = None
     unsigned = _jwt_format.create_unsigned_compact(self._algorithm,
                                                    type_header,
                                                    raw_jwt.json_payload())
     return _jwt_format.create_signed_compact(unsigned,
                                              self._compute_mac(unsigned))
예제 #5
0
 def compute_mac_and_encode_with_kid(self, raw_jwt: _raw_jwt.RawJwt,
                                     kid: Optional[Text]) -> Text:
   """Computes a MAC and encodes the token."""
   if raw_jwt.has_type_header():
     type_header = raw_jwt.type_header()
   else:
     type_header = None
   # TODO(juerg): Add support for custom_kid.
   unsigned = _jwt_format.create_unsigned_compact(self._algorithm, type_header,
                                                  kid, raw_jwt.json_payload())
   return _jwt_format.create_signed_compact(unsigned,
                                            self._compute_mac(unsigned))
예제 #6
0
def validate(validator: JwtValidator, raw_jwt: _raw_jwt.RawJwt) -> None:
    """Validates a jwt.RawJwt and raises JwtInvalidError if it is invalid.

  This function is called by the JWT primitives and does not need to be called
  by the user.

  Args:
    validator: a jwt.JwtValidator that defines how to validate tokens.
    raw_jwt: a jwt.RawJwt token to validate.
  Raises:
    jwt.JwtInvalidError
  """
    if validator.has_fixed_now():
        now = validator.fixed_now()
    else:
        now = datetime.datetime.now(tz=datetime.timezone.utc)
    if not raw_jwt.has_expiration() and not validator.allow_missing_expiration(
    ):
        raise _jwt_error.JwtInvalidError('token is missing an expiration')
    if (raw_jwt.has_expiration()
            and raw_jwt.expiration() <= now - validator.clock_skew()):
        raise _jwt_error.JwtInvalidError('token has expired since %s' %
                                         raw_jwt.expiration())
    if (raw_jwt.has_not_before()
            and raw_jwt.not_before() > now + validator.clock_skew()):
        raise _jwt_error.JwtInvalidError('token cannot be used before %s' %
                                         raw_jwt.not_before())
    if validator.expect_issued_in_the_past():
        if not raw_jwt.has_issued_at():
            raise _jwt_error.JwtInvalidError('token is missing iat claim')
        if raw_jwt.issued_at() > now + validator.clock_skew():
            raise _jwt_error.JwtInvalidError(
                'token has a invalid iat claim in the future: %s' %
                raw_jwt.issued_at())
    if validator.has_expected_type_header():
        if not raw_jwt.has_type_header():
            raise _jwt_error.JwtInvalidError(
                'invalid JWT; missing expected type header %s.' %
                validator.expected_type_header())
        if validator.expected_type_header() != raw_jwt.type_header():
            raise _jwt_error.JwtInvalidError(
                'invalid JWT; expected type header %s, but got %s' %
                (validator.expected_type_header(), raw_jwt.type_header()))
    else:
        if raw_jwt.has_type_header() and not validator.ignore_type_header():
            raise _jwt_error.JwtInvalidError(
                'invalid JWT; token has type_header set, but validator not.')
    if validator.has_expected_issuer():
        if not raw_jwt.has_issuer():
            raise _jwt_error.JwtInvalidError(
                'invalid JWT; missing expected issuer %s.' %
                validator.expected_issuer())
        if validator.expected_issuer() != raw_jwt.issuer():
            raise _jwt_error.JwtInvalidError(
                'invalid JWT; expected issuer %s, but got %s' %
                (validator.expected_issuer(), raw_jwt.issuer()))
    else:
        if raw_jwt.has_issuer() and not validator.ignore_issuer():
            raise _jwt_error.JwtInvalidError(
                'invalid JWT; token has issuer set, but validator not.')
    if validator.has_expected_audience():
        if (not raw_jwt.has_audiences()
                or validator.expected_audience() not in raw_jwt.audiences()):
            raise _jwt_error.JwtInvalidError(
                'invalid JWT; missing expected audience %s.' %
                validator.expected_audience())
    else:
        if raw_jwt.has_audiences() and not validator.ignore_audiences():
            raise _jwt_error.JwtInvalidError(
                'invalid JWT; token has audience set, but validator not.')
예제 #7
0
 def compute_mac_and_encode(self, raw_jwt: _raw_jwt.RawJwt) -> Text:
     """Computes a MAC and encodes the token."""
     unsigned = _jwt_format.create_unsigned_compact(self._algorithm,
                                                    raw_jwt.json_payload())
     return _jwt_format.create_signed_compact(unsigned,
                                              self._compute_mac(unsigned))
예제 #8
0
def validate(validator: JwtValidator, raw_jwt: _raw_jwt.RawJwt) -> None:
    """Validates a jwt.RawJwt and raises JwtInvalidError if it is invalid.

  This function is called by the JWT primitives and does not need to be called
  by the user.

  Args:
    validator: a jwt.JwtValidator that defines how to validate tokens.
    raw_jwt: a jwt.RawJwt token to validate.
  Raises:
    jwt.JwtInvalidError
  """
    if validator.has_fixed_now():
        now = validator.fixed_now()
    else:
        now = datetime.datetime.now(tz=datetime.timezone.utc)
    if (raw_jwt.has_expiration()
            and raw_jwt.expiration() < now - validator.clock_skew()):
        raise _raw_jwt.JwtInvalidError('token has expired since %s' %
                                       raw_jwt.expiration())
    if (raw_jwt.has_not_before()
            and raw_jwt.not_before() > now + validator.clock_skew()):
        raise _raw_jwt.JwtInvalidError('token cannot be used before %s' %
                                       raw_jwt.not_before())
    if validator.has_issuer():
        if not raw_jwt.has_issuer():
            raise _raw_jwt.JwtInvalidError(
                'invalid JWT; missing expected issuer %s.' %
                validator.issuer())
        if validator.issuer() != raw_jwt.issuer():
            raise _raw_jwt.JwtInvalidError(
                'invalid JWT; expected issuer %s, but got %s' %
                (validator.issuer(), raw_jwt.issuer()))
    if validator.has_subject():
        if not raw_jwt.has_subject():
            raise _raw_jwt.JwtInvalidError(
                'invalid JWT; missing expected subject %s.' %
                validator.subject())
        if validator.subject() != raw_jwt.subject():
            raise _raw_jwt.JwtInvalidError(
                'invalid JWT; expected subject %s, but got %s' %
                (validator.subject(), raw_jwt.subject()))
    if validator.has_audience():
        if (not raw_jwt.has_audiences()
                or validator.audience() not in raw_jwt.audiences()):
            raise _raw_jwt.JwtInvalidError(
                'invalid JWT; missing expected audience %s.' %
                validator.audience())
    else:
        if raw_jwt.has_audiences():
            raise _raw_jwt.JwtInvalidError(
                'invalid JWT; token has audience set, but validator not.')