anchor.diff:    end;
   end;
   
  -class function TRSA.Verify(const AInput, ASignature, AKey: TBytes;
  +class function TRSA.Verify(const AInput, ASignature, AKey: TBytes;
     AAlg: TRSAAlgorithm): Boolean;
   var
     LPubKeyBIO: pBIO;
     LPubKey: pEVP_PKEY;
     LRsa: pRSA;
  -  LByte: string;
     LCtx: PEVP_MD_CTX;
     LSha: PEVP_MD;
   begin
  
positive.code: {******************************************************************************}
  {                                                                              }
  {  Delphi JOSE Library                                                         }
  {  Copyright (c) 2015-2017 Paolo Rossi                                         }
  {  https://github.com/paolo-rossi/delphi-jose-jwt                              }
  {                                                                              }
  {******************************************************************************}
  {                                                                              }
  {  Licensed under the Apache License, Version 2.0 (the "License");             }
  {  you may not use this file except in compliance with the License.            }
  {  You may obtain a copy of the License at                                     }
  {                                                                              }
  {      http://www.apache.org/licenses/LICENSE-2.0                              }
  {                                                                              }
  {  Unless required by applicable law or agreed to in writing, software         }
  {  distributed under the License is distributed on an "AS IS" BASIS,           }
  {  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.    }
  {  See the License for the specific language governing permissions and         }
  {  limitations under the License.                                              }
  {                                                                              }
  {******************************************************************************}
  
  unit JOSE.Signing.RSA;
  
  interface
  
  uses
    System.SysUtils,
    IdGlobal,
    IdCTypes,
    IdSSLOpenSSLHeaders,
    JOSE.Encoding.Base64;
  
  type
    TRSAAlgorithm = (RS256, RS384, RS512);
    TRSAAlgorithmHelper = record helper for TRSAAlgorithm
      procedure FromString(const AValue: string);
      function ToString: string;
    end;
  
    TRSA = class
    private
      const PKCS1_SIGNATURE_PUBKEY: RawByteString = '-----BEGIN RSA PUBLIC KEY-----';
      class var FOpenSSLHandle: HMODULE;
      class var _PEM_read_bio_RSA_PUBKEY: function(bp : PBIO; x : PPRSA; cb : ppem_password_cb; u: Pointer) : PRSA cdecl;
      class var _EVP_MD_CTX_create: function: PEVP_MD_CTX cdecl;
      class var _EVP_MD_CTX_destroy: procedure(ctx: PEVP_MD_CTX); cdecl;
      class procedure LoadOpenSSL;
    public
      class function Sign(const AInput, AKey: TBytes; AAlg: TRSAAlgorithm): TBytes;
      class function Verify(const AInput, ASignature, AKey: TBytes; AAlg: TRSAAlgorithm): Boolean;
      class function VerifyPublicKey(const AKey: TBytes): Boolean;
      class function VerifyPrivateKey(const AKey: TBytes): Boolean;
    end;
  
  implementation
  
  function ArrayToString(const ASource: array of char): string;
  var
    LSourcePointer: PChar;
    LTarget: string;
  
negative.code:   LSourcePointer := Addr(ASource);
    SetString(LTarget, LSourcePointer, Length(ASource));
    Result := LTarget;
  end;
  
  // Get OpenSSL error and message text
  function ERR_GetErrorMessage_OpenSSL : String;
  var locErrMsg: array [0..160] of Char;
  begin
    ERR_error_string( ERR_get_error, @locErrMsg );
    result := ArrayToString(locErrMsg);
  end;
  
  { TRSAAlgorithmHelper }
  
  procedure TRSAAlgorithmHelper.FromString(const AValue: string);
  begin
    if AValue = 'RS256' then
      Self := RS256
    else if AValue = 'RS384' then
      Self := RS384
    else if AValue = 'RS512' then
      Self := RS512
    else
      raise Exception.Create('Invalid RSA algorithm type');
  end;
  
  function TRSAAlgorithmHelper.ToString: string;
  begin
    case Self of
      RS256: Result := 'RS256';
      RS384: Result := 'RS384';
      RS512: Result := 'RS512';
    end;
  end;
  
  { TRSA }
  
  class function TRSA.Sign(const AInput, AKey: TBytes;
    AAlg: TRSAAlgorithm): TBytes;
  var
    LPrivKeyBIO: pBIO;
  