Browse Source

fcl-hash: test rsa encrypt/decrypt

mattias 3 years ago
parent
commit
0a44e3192d
2 changed files with 119 additions and 2 deletions
  1. 1 0
      packages/fcl-hash/src/fprsa.pas
  2. 118 2
      packages/fcl-hash/tests/utestpem.pp

+ 1 - 0
packages/fcl-hash/src/fprsa.pas

@@ -377,6 +377,7 @@ begin
     {$ENDIF}
     {$ENDIF}
 
 
     // Encrypt the Block
     // Encrypt the Block
+    // Note: the RSA.M was set in RSAInitFromPublicKey
     Decrypted:=BIImport(RSA.Context,Imported,Size);
     Decrypted:=BIImport(RSA.Context,Imported,Size);
     if Sign then
     if Sign then
     begin
     begin

+ 118 - 2
packages/fcl-hash/tests/utestpem.pp

@@ -5,26 +5,85 @@ unit utestpem;
 interface
 interface
 
 
 uses
 uses
-  Classes, SysUtils, fpcunit, testregistry, fpasn, fppem, fprsa;
+  Classes, SysUtils, fpcunit, testregistry, basenenc,
+  fpTLSBigInt, fppem, fprsa, fphashutils, fpecc;
 
 
 Type
 Type
 
 
   { TTestPEM }
   { TTestPEM }
 
 
   TTestPEM = Class(TTestCase)
   TTestPEM = Class(TTestCase)
+  protected
+    procedure GetPEM_PrivateKeyRSA2048bit(out PrivatePEM, PublicPEM: string);
   Published
   Published
     Procedure TestLoad;
     Procedure TestLoad;
     Procedure TestRSA_RS256Verify;
     Procedure TestRSA_RS256Verify;
+    Procedure TestRSA_PrivatePublicPEM_NoPassphrase;
   end;
   end;
 
 
 implementation
 implementation
 
 
-uses basenenc, fphashutils, fpecc;
+function LinesToText(Lines: array of string): string;
+var
+  i: Integer;
+begin
+  Result:='';
+  for i:=low(Lines) to High(Lines) do
+    Result:=Result+Lines[i]+sLineBreak;
+end;
 
 
 { TTestPEM }
 { TTestPEM }
 Const
 Const
   PrivateKeyFile = 'private-key.pem';
   PrivateKeyFile = 'private-key.pem';
 
 
+procedure TTestPEM.GetPEM_PrivateKeyRSA2048bit(out PrivatePEM, PublicPEM: string
+  );
+begin
+  // generated with
+  //   openssl genrsa -out private.pem 2048
+  PrivatePEM:=LinesToText([
+    '-----BEGIN RSA PRIVATE KEY-----',
+    'MIIEpQIBAAKCAQEAvkRfGW8psCZ3G4+hBA6W/CR/FHhBLB3k3QLypamPbRFlFBxL',
+    'tOK2NblBybY22vUiMLZbb5x8OoOj/IhOrJAlTqhtbTWLy/0K3qbG09vLm8V40kEK',
+    '8/p0STrp3UmsxHNkccj9MRSKk7pOyEvxSCY6K5JGK1VTsMuDCS7DCYk6Vqr3zjX7',
+    'qedF1PVM+Z5t0B+f//kt3oBETNlic4IooEpG/PN2GUQ0oZpa16DDtfgGu7wT3X3Q',
+    'EZFWLJYQTvGc82NpachBIUvqNdIt1npbK38MXU4IPHVrSN/HdK2nQPSMLdKnTV+E',
+    'h/HcxpfjBjarg+VjgDqlmqJ9bkosOVn35vsg8wIDAQABAoIBAQCZxVwujB7fFFdS',
+    '2QPC6Z+w7DYgbwgNBaP/0vAUXzNhbJuKY0v0Rv4H8U9wHGm9EDyvrdG8JHZqPBX+',
+    'dJNQ97aPGaRGjO4M0NdGFve+JXcqz6/UDWkywYnV3V1A0NhmdPQK2et3DSjqN7qQ',
+    'OoAoVWzR5gf74Zwf2Hpwo3BRdqzFeUYVDOH7e7q1SOf2QeU54kVUG21saJR0wsyH',
+    'oSX8BMU2kmg1Un8ET4FM5xEwhdTZzgFTJVZhc6EfOKVbQt6cKmW3aER3c9vR7M3l',
+    'N6Oq73vqrfmy+jFMwz1SoPObQQ7UAnr7YUowaX0AzxHpYm/afyVm+Toym0qWGrrY',
+    'MY/l+vNRAoGBAOsi72pJj30ApfVbSpx8/8QIpweLbEgAD+Ssd41Kgc4O/N7azB61',
+    'RjzSOs1BGhpAZNU6muAAbucm9EssfG5WTAjIM2W2LVuZXXEVXqEGkIymPz9NGugf',
+    'JaCWLaoibmwHkKa+ZV9kDwasmx/VkbAfAbRWaz49ejdrMmkpCW77lYjHAoGBAM8m',
+    'PVJWvFhQrB21xQGSWKd5iSUn2V92gICeDoORqfVtt/UPOaDT915KzXPh4bJeOwg6',
+    'Kkx5wX6UwaNSRH39loDSY1rsBYioV8bxW0BpBvEJG7KXRbBvxzr0+TJkCHgmGMns',
+    'dhePYUcriCaqpQi1yzf201oLTZ6PlJxkmHQobXJ1AoGBAIgWPg576InmWCa64WHU',
+    'joq8nz8kmFTLhGdK0h56IspJrlyksUKMk8wbuGCW7y6GWlV2h7BhT86Eoxrm8lVB',
+    'qNvkUqrpVzMOfiA2x//WNs7QYQaX75ysejCI+oDfUJ1Be5yl0TH2TSQFvfoctycB',
+    'qxDee08YcaWlaxWl5InRHeh9AoGABm3XZWDPw6XtUZa8oIncOoZpHUAZXP8eid9d',
+    '7/NrZPScyvxH+5fYi5Kiwb/280Q9bMnxWiJFQRp40ArTmV1veFwPPVkp6s3eu4vu',
+    'GxenYX+43lgXj5xIgKntugSkxqXYCxxNpfmLOVw+g4S0Torl3bzJXngPVqZ6JEhy',
+    '+tfuXakCgYEA19/JCD/5pVPJtwyDDAYnUUESK+JfBPq1cTbsxcOq01mp5ntsqR4y',
+    'dtOAmxMASvsqud3XIM5fO5m3Jpl1phiGhCw4nvVLcYzVWxYY+oWoeCSyECgu5tmT',
+    'Fo8vn4EEXCkEAA2YPiEuVcrcYsWkLivCTC19lJDfUNMmpwSdiGz/tDU=',
+    '-----END RSA PRIVATE KEY-----' ]);
+
+  // public key extracted with
+  //   openssl rsa -in private.pem -outform PEM -pubout -out public.pem
+  PublicPEM:=LinesToText([
+    '-----BEGIN PUBLIC KEY-----',
+    'MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAvkRfGW8psCZ3G4+hBA6W',
+    '/CR/FHhBLB3k3QLypamPbRFlFBxLtOK2NblBybY22vUiMLZbb5x8OoOj/IhOrJAl',
+    'TqhtbTWLy/0K3qbG09vLm8V40kEK8/p0STrp3UmsxHNkccj9MRSKk7pOyEvxSCY6',
+    'K5JGK1VTsMuDCS7DCYk6Vqr3zjX7qedF1PVM+Z5t0B+f//kt3oBETNlic4IooEpG',
+    '/PN2GUQ0oZpa16DDtfgGu7wT3X3QEZFWLJYQTvGc82NpachBIUvqNdIt1npbK38M',
+    'XU4IPHVrSN/HdK2nQPSMLdKnTV+Eh/HcxpfjBjarg+VjgDqlmqJ9bkosOVn35vsg',
+    '8wIDAQAB',
+    '-----END PUBLIC KEY-----' ]);
+end;
+
 procedure TTestPEM.TestLoad;
 procedure TTestPEM.TestLoad;
 
 
 Const
 Const
@@ -77,6 +136,63 @@ begin
     Fail('TestRS256Verify');
     Fail('TestRS256Verify');
 end;
 end;
 
 
+procedure TTestPEM.TestRSA_PrivatePublicPEM_NoPassphrase;
+const
+  SecretMsg = 'FreePascal RSA Test';
+var
+  PrivatePEM, PublicPEM, Original, Encrypted, Decrypted: string;
+  DER: TBytes;
+  PrivateRSA, PublicRSA: TRSA;
+  EncryptedLen, DecryptedLen: Integer;
+begin
+  GetPEM_PrivateKeyRSA2048bit(PrivatePEM, PublicPEM);
+
+  RSACreate(PublicRSA);
+  RSACreate(PrivateRSA);
+  try
+    // load public key
+    DER:=PemToDER(PublicPEM,_BEGIN_PUBLIC_KEY,_END_PUBLIC_KEY);
+    if length(DER)=0 then
+      Fail('PemToDER public key');
+    RSAInitFromPublicKeyDER(PublicRSA,DER);
+
+    // load private key
+    DER:=PemToDER(PrivatePEM,_BEGIN_RSA_PRIVATE_KEY,_END_RSA_PRIVATE_KEY);
+    if length(DER)=0 then
+      Fail('PemToDER private rsa key');
+    RSAInitFromPrivateKeyDER(PrivateRSA,DER);
+
+    AssertEquals('PublicRSA.ModulusLen=PrivateRSA.ModulusLen',PublicRSA.ModulusLen,PrivateRSA.ModulusLen);
+    if BICompare(PublicRSA.M,PrivateRSA.M)<>0 then
+      Fail('PublicRSA.M = PrivateRSA.M');
+
+    if BICompare(PublicRSA.E,PrivateRSA.E)<>0 then
+      Fail('PublicRSA.E = PrivateRSA.E');
+
+    Original:=SecretMsg;
+
+    // encrypt
+    SetLength(Encrypted{%H-},PublicRSA.ModulusLen);
+    EncryptedLen:=RSAEncryptSign(PublicRSA,@Original[1],length(Original),@Encrypted[1],false);
+    if EncryptedLen<PublicRSA.ModulusLen then
+      AssertEquals('EncryptedLen = ModulusLen',EncryptedLen,PublicRSA.ModulusLen);
+
+    // decrypt
+    SetLength(Decrypted{%H-},EncryptedLen);
+    DecryptedLen:=RSADecryptVerify(PrivateRSA,@Encrypted[1],@Decrypted[1],EncryptedLen,false);
+
+    if DecryptedLen<>length(Original) then
+      AssertEquals('DecryptedLen = length(Original)',DecryptedLen,length(Original));
+    SetLength(Decrypted,DecryptedLen);
+    if Decrypted<>Original then
+      Fail('Decrypted = Original');
+
+  finally
+    RSAFree(PublicRSA);
+    RSAFree(PrivateRSA);
+  end;
+end;
+
 initialization
 initialization
   RegisterTest(TTestPEM);
   RegisterTest(TTestPEM);
 end.
 end.