예제 #1
0
def make_cookie_content(
    name,
    load,
    sign_key,
    domain=None,
    path=None,
    timestamp="",
    enc_key=None,
    max_age=0,
    sign_alg="SHA256",
):
    """
    Create and return a cookies content

    If you only provide a `seed`, a HMAC gets added to the cookies value
    and this is checked, when the cookie is parsed again.

    If you provide both `seed` and `enc_key`, the cookie gets protected
    by using AEAD encryption. This provides both a MAC over the whole cookie
    and encrypts the `load` in a single step.

    The `seed` and `enc_key` parameters should be byte strings of at least
    16 bytes length each. Those are used as cryptographic keys.

    :param name: Cookie name
    :type name: text
    :param load: Cookie load
    :type load: text
    :param sign_key: A sign_key key for payload signing
    :type sign_key: A :py:class:`cryptojwt.jwk.hmac.SYMKey` instance
    :param domain: The domain of the cookie
    :param path: The path specification for the cookie
    :param timestamp: A time stamp
    :type timestamp: text
    :param enc_key: The key to use for payload encryption.
    :type enc_key: A :py:class:`cryptojwt.jwk.hmac.SYMKey` instance
    :param max_age: The time in seconds for when a cookie will be deleted
    :type max_age: int
    :return: A SimpleCookie instance
    """
    if not timestamp:
        timestamp = str(int(time.time()))

    _cookie_value = sign_enc_payload(
        load, timestamp, sign_key=sign_key, enc_key=enc_key, sign_alg=sign_alg
    )

    content = {name: {"value": _cookie_value}}
    if path is not None:
        content[name]["path"] = path
    if domain is not None:
        content[name]["domain"] = domain

    content[name]["httponly"] = True

    if max_age:
        content[name]["expires"] = in_a_while(seconds=max_age)

    return content
def test_valid():
    assert valid("2000-01-12T00:00:00Z") is False
    current_year = datetime.today().year
    assert valid("%d-01-12T00:00:00Z" % (current_year + 1)) is True
    this_instance = instant()
    assert valid(this_instance) is False  # unless on a very fast machine :-)
    soon = in_a_while(seconds=10)
    assert valid(soon) is True
예제 #3
0
def _expiration(timeout, time_format=None):
    """
    Return an expiration time

    :param timeout: When
    :param time_format: The format of the returned value
    :return: A timeout date
    """
    if timeout == "now":
        return time_util.instant(time_format)
    else:
        # validity time should match lifetime of assertions
        return time_util.in_a_while(minutes=timeout, time_format=time_format)
예제 #4
0
    def create_cookie(self, value, typ, **kwargs):
        cookie = SimpleCookie()
        timestamp = str(utc_time_sans_frac())

        _payload = "::".join([value, timestamp, typ])

        bytes_load = _payload.encode("utf-8")
        bytes_timestamp = timestamp.encode("utf-8")

        cookie_payload = [bytes_load, bytes_timestamp]
        cookie[self.name] = (b"|".join(cookie_payload)).decode('utf-8')
        try:
            ttl = kwargs['ttl']
        except KeyError:
            pass
        else:
            cookie[self.name]["expires"] = in_a_while(seconds=ttl)
        return cookie
def test_later_than_str():
    a = in_a_while(seconds=10)
    b = in_a_while(seconds=20)
    assert later_than(b, a)
    assert later_than(a, b) is False
def test_timeout():
    soon = in_a_while(seconds=-1, time_format="")
    assert valid(soon) is False
예제 #7
0
파일: cookie.py 프로젝트: sklemer1/oidc-op
def make_cookie(name, load, seed, domain="", path="", timestamp="",
                enc_key=None, max_age=0):
    """
    Create and return a cookie

    The cookie is secured against tampering.

    If you only provide a `seed`, a HMAC gets added to the cookies value
    and this is checked, when the cookie is parsed again.

    If you provide both `seed` and `enc_key`, the cookie gets protected
    by using AEAD encryption. This provides both a MAC over the whole cookie
    and encrypts the `load` in a single step.

    The `seed` and `enc_key` parameters should be byte strings of at least
    16 bytes length each. Those are used as cryptographic keys.

    :param name: Cookie name
    :type name: text
    :param load: Cookie load
    :type load: text
    :param seed: A seed key for the HMAC function
    :type seed: byte string
    :param domain: The domain of the cookie
    :param path: The path specification for the cookie
    :param timestamp: A time stamp
    :type timestamp: text
    :param enc_key: The key to use for cookie encryption.
    :type enc_key: byte string
    :param max_age: The time in seconds for when a cookie will be deleted
    :type max_age: int
    :return: A SimpleCookie instance
    """
    cookie = SimpleCookie()
    if not timestamp:
        timestamp = str(int(time.time()))

    bytes_load = load.encode("utf-8")
    bytes_timestamp = timestamp.encode("utf-8")

    if enc_key:
        # Make sure the key is 256-bit long, for AES-128-SIV
        #
        # This should go away once we push the keysize requirements up
        # to the top level APIs.
        key = _make_hashed_key((enc_key, seed))

        # key = AESGCM.generate_key(bit_length=128)
        aesgcm = AESGCM(key)
        iv = os.urandom(12)

        # timestamp does not need to be encrypted, just MAC'ed,
        # so we add it to 'Associated Data' only.
        ct = split_ctx_and_tag(aesgcm.encrypt(iv, bytes_load, bytes_timestamp))

        ciphertext, tag = ct
        cookie_payload = [bytes_timestamp,
                          base64.b64encode(iv),
                          base64.b64encode(ciphertext),
                          base64.b64encode(tag)]
    else:
        cookie_payload = [
            bytes_load, bytes_timestamp,
            cookie_signature(seed, load, timestamp).encode('utf-8')]

    cookie[name] = (b"|".join(cookie_payload)).decode('utf-8')
    if path:
        cookie[name]["path"] = path
    if domain:
        cookie[name]["domain"] = domain

    if max_age:
        cookie[name]["expires"] = in_a_while(seconds=max_age)

    return cookie
예제 #8
0
def make_cookie_content(
        name,
        load,
        sign_key,
        domain=None,
        path=None,
        expire=0,
        timestamp="",
        enc_key=None,
        max_age=0,
        sign_alg="SHA256",
        secure=True,
        http_only=True,
        same_site=""
):
    """
    Create and return a cookies content

    If you only provide a `seed`, a HMAC gets added to the cookies value
    and this is checked, when the cookie is parsed again.

    If you provide both `seed` and `enc_key`, the cookie gets protected
    by using AEAD encryption. This provides both a MAC over the whole cookie
    and encrypts the `load` in a single step.

    The `seed` and `enc_key` parameters should be byte strings of at least
    16 bytes length each. Those are used as cryptographic keys.

    :param name: Cookie name
    :type name: text
    :param load: Cookie load
    :type load: text
    :param sign_key: A sign_key key for payload signing
    :type sign_key: A :py:class:`cryptojwt.jwk.hmac.SYMKey` instance
    :param domain: The domain of the cookie
    :param path: The path specification for the cookie
    :param expire: Number of minutes before this cookie goes stale
    :type expire: int
    :param timestamp: A time stamp
    :type timestamp: text
    :param enc_key: The key to use for payload encryption.
    :type enc_key: A :py:class:`cryptojwt.jwk.hmac.SYMKey` instance
    :param max_age: The time in seconds for when a cookie will be deleted
    :type max_age: int
    :param secure: A secure cookie is only sent to the server with an encrypted request over the
    HTTPS protocol.
    :type secure: boolean
    :param http_only: HttpOnly cookies are inaccessible to JavaScript's Document.cookie API
    :type http_only: boolean
    :param same_site: Whether SameSite (None,Strict or Lax) should be added to the cookie
    :type same_site: byte string
    :return: A SimpleCookie instance
    """
    if not timestamp:
        timestamp = str(int(time.time()))

    _cookie_value = sign_enc_payload(
        load, timestamp, sign_key=sign_key, enc_key=enc_key, sign_alg=sign_alg
    )

    content = {name: {"value": _cookie_value}}

    if path is not None:
        content[name]["path"] = path
    if domain is not None:
        content[name]["domain"] = domain
    if max_age:
        content[name]["expires"] = in_a_while(seconds=max_age)
    if path:
        content[name]["path"] = path
    if domain:
        content[name]["domain"] = domain
    if expire:
        content[name]["expires"] = _expiration(expire, "%a, %d-%b-%Y %H:%M:%S GMT")
    if same_site:
        content[name]["SameSite"] = same_site

    # these are booleans so just set them.
    content[name]["Secure"] = secure
    content[name]["httponly"] = http_only


    return content