|
@@ -5,11 +5,10 @@ unit tcjwt;
|
|
interface
|
|
interface
|
|
|
|
|
|
uses
|
|
uses
|
|
- Classes, SysUtils, fpcunit, testregistry, fpjwt;
|
|
|
|
|
|
+ Classes, SysUtils, fpcunit, testregistry, DateUtils, fpjwt, fpjwarsa;
|
|
|
|
|
|
type
|
|
type
|
|
|
|
|
|
-
|
|
|
|
{ TMyClaims }
|
|
{ TMyClaims }
|
|
|
|
|
|
TMyClaims = Class(TClaims)
|
|
TMyClaims = Class(TClaims)
|
|
@@ -36,6 +35,7 @@ type
|
|
protected
|
|
protected
|
|
procedure SetUp; override;
|
|
procedure SetUp; override;
|
|
procedure TearDown; override;
|
|
procedure TearDown; override;
|
|
|
|
+ function CreateUnsignedInput(JOSEAlg, ClaimsIssuer: string): string;
|
|
Property JWT : TJWT Read FJWT;
|
|
Property JWT : TJWT Read FJWT;
|
|
Property Key : TJWTKey Read FKey;
|
|
Property Key : TJWTKey Read FKey;
|
|
published
|
|
published
|
|
@@ -49,6 +49,7 @@ type
|
|
procedure TestVerifySHA384;
|
|
procedure TestVerifySHA384;
|
|
procedure TestVerifyES256;
|
|
procedure TestVerifyES256;
|
|
procedure TestVerifyES256Pem;
|
|
procedure TestVerifyES256Pem;
|
|
|
|
+ procedure TestVerifyRS256Pem;
|
|
end;
|
|
end;
|
|
|
|
|
|
implementation
|
|
implementation
|
|
@@ -116,7 +117,7 @@ Const
|
|
|
|
|
|
|
|
|
|
begin
|
|
begin
|
|
- FKey:=TJWTKey.Create('your-256-bit-secret');
|
|
|
|
|
|
+ FKey.AsString:='your-256-bit-secret';
|
|
FVerifyResult:=TJWT.ValidateJWT(JWTText,FKey);
|
|
FVerifyResult:=TJWT.ValidateJWT(JWTText,FKey);
|
|
AssertNotNull('Have result',FVerifyResult);
|
|
AssertNotNull('Have result',FVerifyResult);
|
|
AssertEquals('Have correct algorithm','HS256',FVerifyResult.JOSE.Alg);
|
|
AssertEquals('Have correct algorithm','HS256',FVerifyResult.JOSE.Alg);
|
|
@@ -152,7 +153,6 @@ Const
|
|
'FEBOl5fjgnPe4gcc5ElXrHDl0jWsshiJ9rS0hlehItc-PKQEzwRKbhcz69V8kwRCUM2rDtuwaXK6DJfO1VOZdw';
|
|
'FEBOl5fjgnPe4gcc5ElXrHDl0jWsshiJ9rS0hlehItc-PKQEzwRKbhcz69V8kwRCUM2rDtuwaXK6DJfO1VOZdw';
|
|
|
|
|
|
begin
|
|
begin
|
|
- FKey:=TJWTKey.Create('mysecretkey');
|
|
|
|
FVerifyResult:=TMyJWT.ValidateJWT(JWTText,FKey);
|
|
FVerifyResult:=TMyJWT.ValidateJWT(JWTText,FKey);
|
|
AssertNotNull('Have result',FVerifyResult);
|
|
AssertNotNull('Have result',FVerifyResult);
|
|
AssertEquals('Correct class',TMyJWT,FVerifyResult.ClassType);
|
|
AssertEquals('Correct class',TMyJWT,FVerifyResult.ClassType);
|
|
@@ -194,7 +194,6 @@ Const
|
|
'8XBKpuFoIEyTxqiP7Rw32VkkxSPGrujBw2ZiKgcX5ZgjH3M8OmTWfYeRDAR6NRVB';
|
|
'8XBKpuFoIEyTxqiP7Rw32VkkxSPGrujBw2ZiKgcX5ZgjH3M8OmTWfYeRDAR6NRVB';
|
|
|
|
|
|
begin
|
|
begin
|
|
- FKey:=TJWTKey.Create('mysecretkey');
|
|
|
|
FVerifyResult:=TMyJWT.ValidateJWT(JWTText,FKey);
|
|
FVerifyResult:=TMyJWT.ValidateJWT(JWTText,FKey);
|
|
AssertNotNull('Have result',FVerifyResult);
|
|
AssertNotNull('Have result',FVerifyResult);
|
|
AssertEquals('Correct class',TMyJWT,FVerifyResult.ClassType);
|
|
AssertEquals('Correct class',TMyJWT,FVerifyResult.ClassType);
|
|
@@ -267,6 +266,7 @@ begin
|
|
S.Free;
|
|
S.Free;
|
|
end;
|
|
end;
|
|
FKey:=TJWTKey.Create(@aPrivateKey,SizeOf(TEccPrivateKey));
|
|
FKey:=TJWTKey.Create(@aPrivateKey,SizeOf(TEccPrivateKey));
|
|
|
|
+ writeln('AAA1 TTestJWT.TestVerifyES256Pem ');
|
|
FVerifyResult:=TMyJWT.ValidateJWT(aInput,FKey);
|
|
FVerifyResult:=TMyJWT.ValidateJWT(aInput,FKey);
|
|
AssertNotNull('Have result',FVerifyResult);
|
|
AssertNotNull('Have result',FVerifyResult);
|
|
AssertEquals('Correct class',TMyJWT,FVerifyResult.ClassType);
|
|
AssertEquals('Correct class',TMyJWT,FVerifyResult.ClassType);
|
|
@@ -279,9 +279,72 @@ begin
|
|
AssertEquals('Have correct admin',False,(TMyJWT(FVerifyResult).Claims as TMyClaims).Admin);
|
|
AssertEquals('Have correct admin',False,(TMyJWT(FVerifyResult).Claims as TMyClaims).Admin);
|
|
end;
|
|
end;
|
|
|
|
|
|
-procedure TTestJWT.SetUp;
|
|
|
|
|
|
+procedure TTestJWT.TestVerifyRS256Pem;
|
|
|
|
+const
|
|
|
|
+ // generated with
|
|
|
|
+ // openssl genrsa -out private.pem 2048
|
|
|
|
+ APrivateKeyPem =
|
|
|
|
+ '-----BEGIN RSA PRIVATE KEY-----'#10+
|
|
|
|
+ 'MIIEpQIBAAKCAQEAvkRfGW8psCZ3G4+hBA6W/CR/FHhBLB3k3QLypamPbRFlFBxL'#10+
|
|
|
|
+ 'tOK2NblBybY22vUiMLZbb5x8OoOj/IhOrJAlTqhtbTWLy/0K3qbG09vLm8V40kEK'#10+
|
|
|
|
+ '8/p0STrp3UmsxHNkccj9MRSKk7pOyEvxSCY6K5JGK1VTsMuDCS7DCYk6Vqr3zjX7'#10+
|
|
|
|
+ 'qedF1PVM+Z5t0B+f//kt3oBETNlic4IooEpG/PN2GUQ0oZpa16DDtfgGu7wT3X3Q'#10+
|
|
|
|
+ 'EZFWLJYQTvGc82NpachBIUvqNdIt1npbK38MXU4IPHVrSN/HdK2nQPSMLdKnTV+E'#10+
|
|
|
|
+ 'h/HcxpfjBjarg+VjgDqlmqJ9bkosOVn35vsg8wIDAQABAoIBAQCZxVwujB7fFFdS'#10+
|
|
|
|
+ '2QPC6Z+w7DYgbwgNBaP/0vAUXzNhbJuKY0v0Rv4H8U9wHGm9EDyvrdG8JHZqPBX+'#10+
|
|
|
|
+ 'dJNQ97aPGaRGjO4M0NdGFve+JXcqz6/UDWkywYnV3V1A0NhmdPQK2et3DSjqN7qQ'#10+
|
|
|
|
+ 'OoAoVWzR5gf74Zwf2Hpwo3BRdqzFeUYVDOH7e7q1SOf2QeU54kVUG21saJR0wsyH'#10+
|
|
|
|
+ 'oSX8BMU2kmg1Un8ET4FM5xEwhdTZzgFTJVZhc6EfOKVbQt6cKmW3aER3c9vR7M3l'#10+
|
|
|
|
+ 'N6Oq73vqrfmy+jFMwz1SoPObQQ7UAnr7YUowaX0AzxHpYm/afyVm+Toym0qWGrrY'#10+
|
|
|
|
+ 'MY/l+vNRAoGBAOsi72pJj30ApfVbSpx8/8QIpweLbEgAD+Ssd41Kgc4O/N7azB61'#10+
|
|
|
|
+ 'RjzSOs1BGhpAZNU6muAAbucm9EssfG5WTAjIM2W2LVuZXXEVXqEGkIymPz9NGugf'#10+
|
|
|
|
+ 'JaCWLaoibmwHkKa+ZV9kDwasmx/VkbAfAbRWaz49ejdrMmkpCW77lYjHAoGBAM8m'#10+
|
|
|
|
+ 'PVJWvFhQrB21xQGSWKd5iSUn2V92gICeDoORqfVtt/UPOaDT915KzXPh4bJeOwg6'#10+
|
|
|
|
+ 'Kkx5wX6UwaNSRH39loDSY1rsBYioV8bxW0BpBvEJG7KXRbBvxzr0+TJkCHgmGMns'#10+
|
|
|
|
+ 'dhePYUcriCaqpQi1yzf201oLTZ6PlJxkmHQobXJ1AoGBAIgWPg576InmWCa64WHU'#10+
|
|
|
|
+ 'joq8nz8kmFTLhGdK0h56IspJrlyksUKMk8wbuGCW7y6GWlV2h7BhT86Eoxrm8lVB'#10+
|
|
|
|
+ 'qNvkUqrpVzMOfiA2x//WNs7QYQaX75ysejCI+oDfUJ1Be5yl0TH2TSQFvfoctycB'#10+
|
|
|
|
+ 'qxDee08YcaWlaxWl5InRHeh9AoGABm3XZWDPw6XtUZa8oIncOoZpHUAZXP8eid9d'#10+
|
|
|
|
+ '7/NrZPScyvxH+5fYi5Kiwb/280Q9bMnxWiJFQRp40ArTmV1veFwPPVkp6s3eu4vu'#10+
|
|
|
|
+ 'GxenYX+43lgXj5xIgKntugSkxqXYCxxNpfmLOVw+g4S0Torl3bzJXngPVqZ6JEhy'#10+
|
|
|
|
+ '+tfuXakCgYEA19/JCD/5pVPJtwyDDAYnUUESK+JfBPq1cTbsxcOq01mp5ntsqR4y'#10+
|
|
|
|
+ 'dtOAmxMASvsqud3XIM5fO5m3Jpl1phiGhCw4nvVLcYzVWxYY+oWoeCSyECgu5tmT'#10+
|
|
|
|
+ 'Fo8vn4EEXCkEAA2YPiEuVcrcYsWkLivCTC19lJDfUNMmpwSdiGz/tDU='#10+
|
|
|
|
+ '-----END RSA PRIVATE KEY-----'#10;
|
|
|
|
+var
|
|
|
|
+ aInput: String;
|
|
|
|
+ Signer: TJWTSignerRS256;
|
|
|
|
+begin
|
|
|
|
+ // header
|
|
|
|
+ jwt.JOSE.alg:='RS256';
|
|
|
|
+
|
|
|
|
+ // claims
|
|
|
|
+ jwt.Claims.exp:=DateTimeToUnix(Now+10);
|
|
|
|
+ jwt.Claims.iss:='FPC JWT';
|
|
|
|
|
|
|
|
+ // load private key from pem
|
|
|
|
+ FKey.AsBytes:=PemToDER(APrivateKeyPem,_BEGIN_RSA_PRIVATE_KEY,_END_RSA_PRIVATE_KEY);
|
|
|
|
|
|
|
|
+ Signer:=TJWTSignerRS256.Create;
|
|
|
|
+ try
|
|
|
|
+ aInput:=Signer.AppendSignature(JWT,Key);
|
|
|
|
+ finally
|
|
|
|
+ Signer.Free;
|
|
|
|
+ end;
|
|
|
|
+
|
|
|
|
+ FVerifyResult:=TMyJWT.ValidateJWT(aInput,FKey);
|
|
|
|
+ AssertNotNull('Have result',FVerifyResult);
|
|
|
|
+ AssertEquals('Correct class',TMyJWT,FVerifyResult.ClassType);
|
|
|
|
+ AssertNotNull('Have result.claims',FVerifyResult.Claims);
|
|
|
|
+ AssertEquals('Correct claims class',TMyClaims,FVerifyResult.Claims.ClassType);
|
|
|
|
+ AssertEquals('Have correct algorithm','RS256',FVerifyResult.JOSE.Alg);
|
|
|
|
+ AssertEquals('Have correct typ','JWT',FVerifyResult.JOSE.typ);
|
|
|
|
+ AssertEquals('Have correct sub','1234567890',FVerifyResult.Claims.sub);
|
|
|
|
+ AssertEquals('Have correct name','John Doe',(TMyJWT(FVerifyResult).Claims as TMyClaims).Name);
|
|
|
|
+ AssertEquals('Have correct admin',False,(TMyJWT(FVerifyResult).Claims as TMyClaims).Admin);
|
|
|
|
+end;
|
|
|
|
+
|
|
|
|
+procedure TTestJWT.SetUp;
|
|
begin
|
|
begin
|
|
Inherited;
|
|
Inherited;
|
|
FKey:=TJWTKey.Create('mysecretkey');
|
|
FKey:=TJWTKey.Create('mysecretkey');
|
|
@@ -300,6 +363,18 @@ begin
|
|
Inherited;
|
|
Inherited;
|
|
end;
|
|
end;
|
|
|
|
|
|
|
|
+function TTestJWT.CreateUnsignedInput(JOSEAlg, ClaimsIssuer: string): string;
|
|
|
|
+var
|
|
|
|
+ IssuedAt, Expire: Int64;
|
|
|
|
+ Header, Claims: String;
|
|
|
|
+begin
|
|
|
|
+ IssuedAt:=DateTimeToUnix(Now-1);
|
|
|
|
+ Expire:=IssuedAt+1000000;
|
|
|
|
+ Header:='{"typ":"JWT","alg":"'+JOSEAlg+'"}';
|
|
|
|
+ Claims:='{"iat":'+IntToStr(IssuedAt)+',"exp":'+IntToStr(Expire)+',"iss":"'+ClaimsIssuer+'"}';
|
|
|
|
+ Result:=Base64URL.Encode(Header,false)+'.'+Base64URL.Encode(Claims,false);
|
|
|
|
+end;
|
|
|
|
+
|
|
initialization
|
|
initialization
|
|
RegisterTest(TTestJWT);
|
|
RegisterTest(TTestJWT);
|
|
end.
|
|
end.
|