<?php

/*
 * The MIT License (MIT)
 *
 * Copyright (c) 2014-2018 Spomky-Labs
 *
 * This software may be modified and distributed under the terms
 * of the MIT license.  See the LICENSE file for details.
 */

use Base64Url\Base64Url;
use Jose\Algorithm\KeyEncryption\A128KW;
use Jose\Algorithm\KeyEncryption\A192KW;
use Jose\Algorithm\KeyEncryption\A256KW;
use Jose\Object\JWK;

/**
 * @group AESKW
 * @group Unit
 */
class AESKWKeyEncryptionTest extends \Jose\Test\BaseTestCase
{
    public function testA128KW()
    {
        $header = [];
        $key = new JWK([
            'kty' => 'oct',
            'k' => Base64Url::encode(hex2bin('000102030405060708090A0B0C0D0E0F')),
        ]);

        $cek = hex2bin('00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F');

        $aeskw = new A128KW();

        $wrapped_cek = $aeskw->wrapKey($key, $cek, $header, $header);

        self::assertEquals($wrapped_cek, hex2bin('11826840774D993FF9C2FA02CCA3CEA0E93B1E1CF96361F93EA6DC2F345194E7B30F964C79F9E61D'));
        self::assertEquals($cek, $aeskw->unwrapKey($key, $wrapped_cek, $header));
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage  Wrong key type
     */
    public function testBadKey()
    {
        $header = [];
        $key = new JWK([
            'kty' => 'EC',
        ]);

        $cek = hex2bin('00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F');

        $aeskw = new A128KW();

        $aeskw->wrapKey($key, $cek, $header, $header);
    }

    public function testA192KW()
    {
        $header = [];
        $key = new JWK([
            'kty' => 'oct',
            'k' => Base64Url::encode(hex2bin('000102030405060708090A0B0C0D0E0F1011121314151617')),
        ]);

        $cek = hex2bin('00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F');

        $aeskw = new A192KW();

        $wrapped_cek = $aeskw->wrapKey($key, $cek, $header, $header);

        self::assertEquals($wrapped_cek, hex2bin('08861E000AABFA4479C7191F9DC51CCA37C50F16CC14441C6EA4980CFCE0F41D9285758C6F74AC6D'));
        self::assertEquals($cek, $aeskw->unwrapKey($key, $wrapped_cek, $header));
    }

    public function testA256KW()
    {
        $header = [];
        $key = new JWK([
            'kty' => 'oct',
            'k' => Base64Url::encode(hex2bin('000102030405060708090A0B0C0D0E0F101112131415161718191A1B1C1D1E1F')),
        ]);

        $cek = hex2bin('00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F');

        $aeskw = new A256KW();

        $wrapped_cek = $aeskw->wrapKey($key, $cek, $header, $header);

        self::assertEquals($wrapped_cek, hex2bin('28C9F404C4B810F4CBCCB35CFB87F8263F5786E2D80ED326CBC7F0E71A99F43BFB988B9B7A02DD21'));
        self::assertEquals($cek, $aeskw->unwrapKey($key, $wrapped_cek, $header));
    }

    /**
     * @expectedException \InvalidArgumentException
     * @expectedExceptionMessage The key size is not valid
     */
    public function testBadKeySize()
    {
        $header = [];
        $key = new JWK([
            'kty' => 'oct',
            'k' => Base64Url::encode(hex2bin('000102030405060708090A0B0C0D0E0F')),
        ]);

        $cek = hex2bin('00112233445566778899AABBCCDDEEFF000102030405060708090A0B0C0D0E0F');

        $aeskw = new A256KW();

        $wrapped_cek = $aeskw->wrapKey($key, $cek, $header, $header);

        $aeskw->unwrapKey($key, $wrapped_cek, $header);
    }
}
