123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306 |
- unit tcjwt;
- {$mode objfpc}{$H+}
- interface
- uses
- Classes, SysUtils, fpcunit, testregistry, fpjwt;
- type
- { TMyClaims }
- TMyClaims = Class(TClaims)
- private
- FAdmin: Boolean;
- FName: string;
- Published
- Property Name : string Read FName Write FName;
- Property admin : Boolean Read FAdmin Write FAdmin;
- end;
- { TMyJWT }
- TMyJWT = Class(TJWT)
- Function CreateClaims : TClaims; override;
- end;
- { TTestJWT }
- TTestJWT= class(TTestCase)
- private
- FJWT: TJWT;
- FKey : TJWTKey;
- FVerifyResult : TJWT;
- protected
- procedure SetUp; override;
- procedure TearDown; override;
- Property JWT : TJWT Read FJWT;
- Property Key : TJWTKey Read FKey;
- published
- procedure TestSignNone;
- procedure TestVerifyNone;
- procedure TestSignSHA256;
- procedure TestVerifySHA256;
- procedure TestSignSHA512;
- procedure TestVerifySHA512;
- procedure TestSignSHA384;
- procedure TestVerifySHA384;
- procedure TestVerifyES256;
- procedure TestVerifyES256Pem;
- end;
- implementation
- uses
- basenenc, sha256, fpjwasha256, sha512, fpjwasha512, fpjwasha384, fpjwaes256, fpecc, fppem;
- { TMyJWT }
- function TMyJWT.CreateClaims: TClaims;
- begin
- Result:=TMyClaims.Create;
- end;
- procedure TTestJWT.TestSignNone;
- Var
- P1,P2 : String;
- begin
- P1:=FJWT.JOSE.AsEncodedString;
- P2:=FJWT.Claims.AsEncodedString;
- AssertEquals('Signed with none',P1+'.'+P2+'.',FJWT.Sign(TJWTKey.Empty));
- end;
- procedure TTestJWT.TestVerifyNone;
- Var
- aJWT : String;
- begin
- aJWT:=FJWT.AsEncodedString;
- FVerifyResult:=TJWT.ValidateJWT(aJWT,TJWTKey.Empty,TMyJWT);
- AssertNotNull('Have result',FVerifyResult);
- AssertEquals('Correct class',TMyJWT,FVerifyResult.ClassType);
- end;
- procedure TTestJWT.TestSignSHA256;
- Var
- Sign,P1,P2 : UTF8String;
- aDigest : TSHA256Digest;
- B : TBytes;
- begin
- FJWT.JOSE.alg:='HS256';
- // Writeln('JOSE: ',FJWT.JOSE.AsString);
- // Writeln('Claims: ',FJWT.Claims.AsString);
- P1:=FJWT.JOSE.AsEncodedString;
- P2:=FJWT.Claims.AsEncodedString;
- B:=TEncoding.UTF8.GetAnsiBytes(P1+'.'+P2);
- if not TSHA256.HMAC(FKey.AsPointer,FKey.Length,PByte(B),Length(B),aDigest) then
- Fail('Could not HMAC');
- Sign:=Base64URL.Encode(@aDigest[0],Length(aDigest),False);
- // Writeln('Signed: ',P1+'.'+P2+'.'+Sign);
- AssertEquals('Signed with SHA256',P1+'.'+P2+'.'+Sign,FJWT.Sign(FKey));
- end;
- procedure TTestJWT.TestVerifySHA256;
- Const
- JWTText ='eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.'+
- 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ.'+
- 'SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c';
- begin
- FKey:=TJWTKey.Create('your-256-bit-secret');
- FVerifyResult:=TJWT.ValidateJWT(JWTText,FKey);
- AssertNotNull('Have result',FVerifyResult);
- AssertEquals('Have correct algorithm','HS256',FVerifyResult.JOSE.Alg);
- AssertEquals('Have correct typ','JWT',FVerifyResult.JOSE.typ);
- AssertEquals('Have correct sub','1234567890',FVerifyResult.Claims.sub);
- end;
- procedure TTestJWT.TestSignSHA512;
- Var
- Sign,P1,P2 : UTF8String;
- aDigest : TSHA512Digest;
- B : TBytes;
- begin
- FJWT.JOSE.alg:='HS512';
- // Writeln('JOSE: ',FJWT.JOSE.AsString);
- // Writeln('Claims: ',FJWT.Claims.AsString);
- P1:=FJWT.JOSE.AsEncodedString;
- P2:=FJWT.Claims.AsEncodedString;
- B:=TEncoding.UTF8.GetAnsiBytes(P1+'.'+P2);
- if not TSHA512.HMAC(FKey.AsPointer,FKey.Length,PByte(B),Length(B),aDigest) then
- Fail('Could not HMAC');
- Sign:=Base64URL.Encode(@aDigest[0],Length(aDigest),False);
- // Writeln('Signed: ',P1+'.'+P2+'.'+Sign);
- AssertEquals('Signed with SHA512',P1+'.'+P2+'.'+Sign,FJWT.Sign(FKey));
- end;
- procedure TTestJWT.TestVerifySHA512;
- Const
- JWTText = 'eyJhbGciOiJIUzUxMiIsInR5cCI6IkpXVCJ9.'+
- 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.'+
- 'FEBOl5fjgnPe4gcc5ElXrHDl0jWsshiJ9rS0hlehItc-PKQEzwRKbhcz69V8kwRCUM2rDtuwaXK6DJfO1VOZdw';
- begin
- FKey:=TJWTKey.Create('mysecretkey');
- FVerifyResult:=TMyJWT.ValidateJWT(JWTText,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','HS512',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',true,(TMyJWT(FVerifyResult).Claims as TMyClaims).Admin);
- end;
- procedure TTestJWT.TestSignSHA384;
- Var
- Sign,P1,P2 : UTF8String;
- aDigest : TSHA384Digest;
- B : TBytes;
- begin
- FJWT.JOSE.alg:='HS384';
- // Writeln('JOSE: ',FJWT.JOSE.AsString);
- // Writeln('Claims: ',FJWT.Claims.AsString);
- P1:=FJWT.JOSE.AsEncodedString;
- P2:=FJWT.Claims.AsEncodedString;
- B:=TEncoding.UTF8.GetAnsiBytes(P1+'.'+P2);
- if not TSHA384.HMAC(FKey.AsPointer,FKey.Length,PByte(B),Length(B),aDigest) then
- Fail('Could not HMAC');
- Sign:=Base64URL.Encode(@aDigest[0],Length(aDigest),False);
- // Writeln('Signed: ',P1+'.'+P2+'.'+Sign);
- AssertEquals('Signed with SHA384',P1+'.'+P2+'.'+Sign,FJWT.Sign(FKey));
- end;
- procedure TTestJWT.TestVerifySHA384;
- Const
- JWTText =
- 'eyJhbGciOiJIUzM4NCIsInR5cCI6IkpXVCJ9.'+
- 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.'+
- '8XBKpuFoIEyTxqiP7Rw32VkkxSPGrujBw2ZiKgcX5ZgjH3M8OmTWfYeRDAR6NRVB';
- begin
- FKey:=TJWTKey.Create('mysecretkey');
- FVerifyResult:=TMyJWT.ValidateJWT(JWTText,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','HS384',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',true,(TMyJWT(FVerifyResult).Claims as TMyClaims).Admin);
- end;
- procedure TTestJWT.TestVerifyES256;
- Const
- // from JWT.IO
- aJWT =
- 'eyJhbGciOiJFUzI1NiIsInR5cCI6IkpXVCJ9.'+
- 'eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiYWRtaW4iOnRydWUsImlhdCI6MTUxNjIzOTAyMn0.'+
- 'tyh-VfuzIxCyGYDlkBA7DfyjrqmSHu6pQ2hoZuFqUSLPNY2N0mpHb3nk5K17HWP_3cYHBw7AhHale5wky6-sVA';
- Var
- aPrivateKey2: TEccPrivateKey = ($7a,$f6,$73,$2f,$58,$1d,$00,$5a,$fc,$f2,$16,$f6,$38,$5f,$f6,
- $37,$10,$29,$24,$2c,$c6,$08,$40,$dd,$7d,$2a,$7a,$55,$03,$b7,
- $d2,$1c);
- begin
- FKey:=TJWTKey.Create(@aPrivateKey2,SizeOf(TEccPrivateKey));
- FVerifyResult:=TMyJWT.ValidateJWT(aJWT,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','ES256',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',true,(TMyJWT(FVerifyResult).Claims as TMyClaims).Admin);
- end;
- procedure TTestJWT.TestVerifyES256Pem;
- Const
- aInput =
- 'eyJ0eXAiOiJKV1QiLCJhbGciOiJFUzI1NiJ9.' +
- 'eyJpYXQiOjE1MTYyMzkwMjIsImV4cCI6MTUxNjI0OTAyMiwiaXNzIjoiRGVscGhpIEpPU0UgYW5kIEpXVCBMaWJyYXJ5In0.'+
- '4QDMKAvHwb6pA5fN0oQjlzuKmPIlNpmIQ8vPH7zy4fjZdtcPVJMtfiVhztwQldQL9A5yzBKI8q2puVygm-2Adw';
- // Private key in PEM format
- Const APrivateKeyPem =
- '-----BEGIN EC PRIVATE KEY-----'+ #10+
- 'MHcCAQEEIFzS3/5bCnrlpa4902/zkYzURF6E2D8pazgnJu4smhpQoAoGCCqGSM49'+ #10+
- 'AwEHoUQDQgAEqTjyg2z65i+zbyUZW8BQ+K87DNsICRaEH7Fy7Rm3MseXy9ItSCQU'+ #10+
- 'VeJbtO6kYUA00mx7bKoC1sx5sbtFExnYPQ=='+ #10+
- '-----END EC PRIVATE KEY-----';
- Var
- S : TStringStream;
- aPrivateKey : TEccPrivateKey;
- aPublicKey : TEccPublicKey;
- X,Y : AnsiString;
- begin
- S:=TStringStream.Create(aPrivateKeyPem);
- try
- PemLoadECDSA(S,aPrivateKey,aPublicKey,X,Y);
- finally
- S.Free;
- end;
- FKey:=TJWTKey.Create(@aPrivateKey,SizeOf(TEccPrivateKey));
- 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','ES256',FVerifyResult.JOSE.Alg);
- AssertEquals('Have correct typ','JWT',FVerifyResult.JOSE.typ);
- AssertEquals('Have correct sub','',FVerifyResult.Claims.sub);
- AssertEquals('Have correct name','',(TMyJWT(FVerifyResult).Claims as TMyClaims).Name);
- AssertEquals('Have correct admin',False,(TMyJWT(FVerifyResult).Claims as TMyClaims).Admin);
- end;
- procedure TTestJWT.SetUp;
- begin
- Inherited;
- FKey:=TJWTKey.Create('mysecretkey');
- FJWT:=TMyJWT.Create;
- FJWT.JOSE.alg:='none';
- FJWT.JOSE.typ:='JWT';
- FJWT.Claims.sub:='1234567890';
- FJWT.Claims.iat:=1516239022;
- (FJWT.Claims as TMyClaims).Name:='John Doe';
- end;
- procedure TTestJWT.TearDown;
- begin
- FreeAndNil(FJWT);
- FreeAndNil(FVerifyResult);
- Inherited;
- end;
- initialization
- RegisterTest(TTestJWT);
- end.
|