Exemple #1
0
 void
 coverQuantisationCornerCases()
   {
     // origin at lower end of the time range
     FixedFrameQuantiser case1 (1, Time::MIN);
     CHECK (secs(0)            == case1.gridAlign(Time::MIN  ));
     CHECK (secs(0)            == case1.gridAlign(Time::MIN +TimeValue(1) ));
     CHECK (secs(1)            == case1.gridAlign(Time::MIN +secs(1) ));
     CHECK (Time::MAX -secs(1) >  case1.gridAlign( secs(-1)  ));
     CHECK (Time::MAX -secs(1) <= case1.gridAlign( secs (0)  ));
     CHECK (Time::MAX          >  case1.gridAlign( secs (0)  ));
     CHECK (Time::MAX          == case1.gridAlign( secs(+1)  ));
     CHECK (Time::MAX          == case1.gridAlign( secs(+2)  ));
     
     // origin at upper end of the time range
     FixedFrameQuantiser case2 (1, Time::MAX);
     CHECK (secs( 0)           == case2.gridAlign(Time::MAX  ));
     CHECK (secs(-1)           == case2.gridAlign(Time::MAX -TimeValue(1) ));  // note: next lower frame
     CHECK (secs(-1)           == case2.gridAlign(Time::MAX -secs(1) ));      //        i.e. the same as a whole frame down
     CHECK (Time::MIN +secs(1) <  case2.gridAlign( secs(+2)  ));
     CHECK (Time::MIN +secs(1) >= case2.gridAlign( secs(+1)  ));
     CHECK (Time::MIN          <  case2.gridAlign( secs(+1)  ));
     CHECK (Time::MIN          == case2.gridAlign( secs( 0)  ));          //      note: because of downward truncating,
     CHECK (Time::MIN          == case2.gridAlign( secs(-1)  ));         //             resulting values will already exceed
     CHECK (Time::MIN          == case2.gridAlign( secs(-2)  ));        //              allowed range and thus will be clipped
     
     // maximum frame size is half the time range
     Duration hugeFrame(Time::MAX);
     FixedFrameQuantiser case3 (hugeFrame);
     CHECK (Time::MIN          == case3.gridAlign(Time::MIN  ));
     CHECK (Time::MIN          == case3.gridAlign(Time::MIN +TimeValue(1) ));
     CHECK (Time::MIN          == case3.gridAlign( secs(-1)  ));
     CHECK (TimeValue(0)       == case3.gridAlign( secs( 0)  ));
     CHECK (TimeValue(0)       == case3.gridAlign( secs(+1)  ));
     CHECK (TimeValue(0)       == case3.gridAlign(Time::MAX -TimeValue(1) ));
     CHECK (Time::MAX          == case3.gridAlign(Time::MAX  ));
     
     // now displacing this grid by +1sec....
     FixedFrameQuantiser case4 (hugeFrame, secs(1));
     CHECK (Time::MIN          == case4.gridAlign(Time::MIN  ));
     CHECK (Time::MIN          == case4.gridAlign(Time::MIN +TimeValue(1) ));  // clipped...
     CHECK (Time::MIN          == case4.gridAlign(Time::MIN +secs(1) ));      //  but now exact (unclipped)
     CHECK (Time::MIN          == case4.gridAlign( secs(-1)  ));
     CHECK (Time::MIN          == case4.gridAlign( secs( 0)  ));
     CHECK (TimeValue(0)       == case4.gridAlign( secs(+1)  ));           //.....now exactly the frame number zero
     CHECK (TimeValue(0)       == case4.gridAlign(Time::MAX -TimeValue(1) ));
     CHECK (TimeValue(0)       == case4.gridAlign(Time::MAX  ));         //.......still truncated down to frame #0
     
     // larger frames aren't possible
     Duration not_really_larger(secs(10000) + hugeFrame);
     CHECK (hugeFrame == not_really_larger);
     
     // frame sizes below the time micro grid get trapped
     long subAtomic = 2*GAVL_TIME_SCALE;                           // too small for this universe...
     VERIFY_ERROR (BOTTOM_VALUE, FixedFrameQuantiser quark(subAtomic) );
     VERIFY_ERROR (BOTTOM_VALUE, FixedFrameQuantiser quark(Duration (FSecs (1,subAtomic))) );
   }
      /** @test OpaqueHolder with additional storage for subclass.
       *        When a subclass requires more storage than the base class or
       *        Interface, we need to create a custom OpaqueHolder, specifying the
       *        actually necessary storage. Such a custom OpaqueHolder behaves exactly
       *        like the standard variant, but there is protection against accidentally
       *        using a standard variant to hold an instance of the larger subclass.
       *        
       *  @test Moreover, if the concrete class has a custom operator bool(), it
       *        will be invoked automatically from OpaqueHolder's operator bool()
       * 
       */ 
      void
      checkSpecialSubclass ()
        {
          typedef OpaqueHolder<Base, sizeof(Special)> SpecialOpaque;
          
          cout << showSizeof<Base>() << endl;
          cout << showSizeof<Special>() << endl;
          cout << showSizeof<Opaque>() << endl;
          cout << showSizeof<SpecialOpaque>() << endl;
          
          CHECK (sizeof(Special) > sizeof(Base));
          CHECK (sizeof(SpecialOpaque) > sizeof(Opaque));
          CHECK (sizeof(SpecialOpaque) <= sizeof(Special) + sizeof(void*) + _ALIGN_);
          
          Special s1 (6);
          Special s2 (3);
          CHECK (!s1);               // even value
          CHECK (s2);                // odd value
          CHECK (7 == s1.getIt());   // indeed subclass of DD<7>
          CHECK (7 == s2.getIt());
          
          SpecialOpaque ospe0;
          SpecialOpaque ospe1 (s1);
          SpecialOpaque ospe2 (s2);
          
          CHECK (!ospe0);            // note: bool test (isValid)
          CHECK (!ospe1);            // also forwarded to contained object (myVal_==6 is even)
          CHECK ( ospe2);
          CHECK ( isnil(ospe0));     // while isnil just checks the empty state
          CHECK (!isnil(ospe1));
          CHECK (!isnil(ospe2));
          
          CHECK (7 == ospe1->getIt());
          CHECK (6 == ospe1.get<Special>().myVal_);
          CHECK (3 == ospe2.get<Special>().myVal_);
          
          ospe1 = DD<5>();            // but can be reassigned like any normal Opaque
          CHECK (ospe1);
          CHECK (5 == ospe1->getIt());
          VERIFY_ERROR (WRONG_TYPE, ospe1.get<Special>() );
          
          Opaque normal = DD<5>();
          CHECK (normal);
          CHECK (5 == normal->getIt());
#if false ////////////////////////////////////////////////////////TODO: restore throwing ASSERT
          // Assertion protects against SEGV
          VERIFY_ERROR (ASSERTION, normal = s1 );
#endif////////////////////////////////////////////////////////////
        }
Exemple #3
0
 void
 checkStateCapturingMechanism ()
   {
     function<void(short,int)> undo_func  = undo;
     function< int(short)>     cap_func   = capture;
     
     MemHolder mementoHolder (undo_func,cap_func);
     
     CHECK (sizeof(MemHolder) <= sizeof(int)                    // storage for the memento
                                + 2 * sizeof(function<void()>)  // storage for the 2 undecorated functors
                                + ALIGNMENT);
     
     function<OpSIG> bound_undo_func = mementoHolder.tieUndoFunc();
     function<OpSIG> bound_cap_func  = mementoHolder.tieCaptureFunc();
     
     VERIFY_ERROR (MISSING_MEMENTO, bound_undo_func(123) );
     VERIFY_ERROR (MISSING_MEMENTO, mementoHolder.getState() );
     
     short rr (rand() %100);
     testVal = 0;
     bound_cap_func(rr);     // invoke state capturing 
     
     CHECK (rr == mementoHolder.getState());
     
     testVal = 10;           // meanwhile "somehow" mutate the state
     bound_undo_func(0);     // invoking the undo() feeds back the memento
     CHECK (testVal == 10-rr);
     
     // this cycle can be repeated with different state values
     rr = (rand() %100);
     testVal = rr;
     bound_cap_func(5);      // capture new state
     CHECK (5+rr == mementoHolder.getState());
     
     testVal = -20;
     bound_undo_func(3*rr);
     CHECK (testVal == -20 + 3*rr - (5+rr));
   }
      /** @test cover the basic situations of object handling,
       *        especially copy operations and re-assignments
       */
      void
      checkHandling (TestList& objs)
        {
          Opaque oo;
          CHECK (!oo);
          CHECK (isnil(oo));
          
          oo = objs[1];
          CHECK (oo);
          CHECK (!isnil(oo));
          
          typedef DD<3> D3;
          typedef DD<5> D5;
          D3 d3 (oo.get<D3>() );
          CHECK (3 == oo->getIt());    // re-access through Base interface
          CHECK (!isSameObject (d3, *oo));
          VERIFY_ERROR (WRONG_TYPE, oo.get<D5>() );
          
          // direct assignment of target into Buffer
          oo = D5();
          CHECK (oo);
          CHECK (5 == oo->getIt());
          VERIFY_ERROR (WRONG_TYPE, oo.get<D3>() );
          
          // can get a direct reference to contained object
          D5 &rd5 (oo.get<D5>()); 
          CHECK (isSameObject (rd5, *oo));
          
          CHECK (!isnil(oo));
          oo = objs[3];     // copy construction also works on non-empty object
          CHECK (7 == oo->getIt());
          
          // WARNING: direct ref has been messed up through the backdoor!
          CHECK (7 == rd5.getIt());
          CHECK (isSameObject (rd5, *oo));
          
          uint cnt_before = _create_count;
          
          oo.clear();
          CHECK (!oo);
          oo = D5();        // direct assignment also works on empty object
          CHECK (oo);
          CHECK (5 == oo->getIt());
          CHECK (_create_count == 2 + cnt_before);
          // one within buff and one for the anonymous temporary D5()
          
          
          // verify that self-assignment is properly detected...
          cnt_before = _create_count;
          oo = oo;
          CHECK (oo);
          CHECK (_create_count == cnt_before);
          oo = oo.get<D5>();
          CHECK (_create_count == cnt_before);
          oo = *oo;
          CHECK (_create_count == cnt_before);
          CHECK (oo);
          
          oo.clear();
          CHECK (!oo);
          CHECK (isnil(oo));
          VERIFY_ERROR (BOTTOM_VALUE, oo.get<D5>() );
#if false ///////////////////////////////////////////////////////////////////////////////////////////////TICKET #537 : restore throwing ASSERT
          VERIFY_ERROR (ASSERTION, oo->getIt() );
#endif    ///////////////////////////////////////////////////////////////////////////////////////////////TICKET #537 : restore throwing ASSERT
          // can't access empty holder...
          
          Opaque o1 (oo);
          CHECK (!o1);
          
          Opaque o2 (d3);
          CHECK (!isSameObject (d3, *o2));
          CHECK (3 == o2->getIt());
          
          CHECK (sizeof(Opaque) <= sizeof(Base) + sizeof(void*) + _ALIGN_);
        }
Exemple #5
0
int jwt_verify_sha_pem(jwt_t *jwt, const char *head, const char *sig_b64)
{
	unsigned char *sig = NULL;
	EVP_MD_CTX *mdctx = NULL;
	ECDSA_SIG *ec_sig = NULL;
	BIGNUM *ec_sig_r = NULL;
	BIGNUM *ec_sig_s = NULL;
	EVP_PKEY *pkey = NULL;
	const EVP_MD *alg;
	int type;
	int pkey_type;
	BIO *bufkey = NULL;
	int ret = 0;
	int slen;

	switch (jwt->alg) {
	/* RSA */
	case JWT_ALG_RS256:
		alg = EVP_sha256();
		type = EVP_PKEY_RSA;
		break;
	case JWT_ALG_RS384:
		alg = EVP_sha384();
		type = EVP_PKEY_RSA;
		break;
	case JWT_ALG_RS512:
		alg = EVP_sha512();
		type = EVP_PKEY_RSA;
		break;

	/* ECC */
	case JWT_ALG_ES256:
		alg = EVP_sha256();
		type = EVP_PKEY_EC;
		break;
	case JWT_ALG_ES384:
		alg = EVP_sha384();
		type = EVP_PKEY_EC;
		break;
	case JWT_ALG_ES512:
		alg = EVP_sha512();
		type = EVP_PKEY_EC;
		break;

	default:
		return EINVAL;
	}

	sig = jwt_b64_decode(sig_b64, &slen);
	if (sig == NULL)
		VERIFY_ERROR(EINVAL);

	bufkey = BIO_new_mem_buf(jwt->key, jwt->key_len);
	if (bufkey == NULL)
		VERIFY_ERROR(ENOMEM);

	/* This uses OpenSSL's default passphrase callback if needed. The
	 * library caller can override this in many ways, all of which are
	 * outside of the scope of LibJWT and this is documented in jwt.h. */
	pkey = PEM_read_bio_PUBKEY(bufkey, NULL, NULL, NULL);
	if (pkey == NULL)
		VERIFY_ERROR(EINVAL);

	pkey_type = EVP_PKEY_id(pkey);
	if (pkey_type != type)
		VERIFY_ERROR(EINVAL);

	/* Convert EC sigs back to ASN1. */
	if (pkey_type == EVP_PKEY_EC) {
		unsigned int degree, bn_len;
		unsigned char *p;
		EC_KEY *ec_key;

		ec_sig = ECDSA_SIG_new();
		if (ec_sig == NULL)
			VERIFY_ERROR(ENOMEM);

		/* Get the actual ec_key */
		ec_key = EVP_PKEY_get1_EC_KEY(pkey);
		if (ec_key == NULL)
			VERIFY_ERROR(ENOMEM);

		degree = EC_GROUP_get_degree(EC_KEY_get0_group(ec_key));

		EC_KEY_free(ec_key);

		bn_len = (degree + 7) / 8;
		if ((bn_len * 2) != slen)
			VERIFY_ERROR(EINVAL);

		ec_sig_r = BN_bin2bn(sig, bn_len, NULL);
		ec_sig_s = BN_bin2bn(sig + bn_len, bn_len, NULL);
		if (ec_sig_r  == NULL || ec_sig_s == NULL)
			VERIFY_ERROR(EINVAL);

		ECDSA_SIG_set0(ec_sig, ec_sig_r, ec_sig_s);
		free(sig);

		slen = i2d_ECDSA_SIG(ec_sig, NULL);
		sig = malloc(slen);
		if (sig == NULL)
			VERIFY_ERROR(ENOMEM);

		p = sig;
		slen = i2d_ECDSA_SIG(ec_sig, &p);

		if (slen == 0)
			VERIFY_ERROR(EINVAL);
	}

	mdctx = EVP_MD_CTX_create();
	if (mdctx == NULL)
		VERIFY_ERROR(ENOMEM);

	/* Initialize the DigestVerify operation using alg */
	if (EVP_DigestVerifyInit(mdctx, NULL, alg, NULL, pkey) != 1)
		VERIFY_ERROR(EINVAL);

	/* Call update with the message */
	if (EVP_DigestVerifyUpdate(mdctx, head, strlen(head)) != 1)
		VERIFY_ERROR(EINVAL);

	/* Now check the sig for validity. */
	if (EVP_DigestVerifyFinal(mdctx, sig, slen) != 1)
		VERIFY_ERROR(EINVAL);

jwt_verify_sha_pem_done:
	if (bufkey)
		BIO_free(bufkey);
	if (pkey)
		EVP_PKEY_free(pkey);
	if (mdctx)
		EVP_MD_CTX_destroy(mdctx);
	if (sig)
		free(sig);
	if (ec_sig)
		ECDSA_SIG_free(ec_sig);

	return ret;
}