mainform.pas

来自「著名的SecureBlackBox控件完整源码」· PAS 代码 · 共 966 行 · 第 1/3 页

PAS
966
字号
          HMACKeyData.Key.Key := Buf;
          Signer.KeyData := HMACKeyData;
        end
        else
        begin
          if Assigned(Cert) and Cert.PrivateKeyExists then
          begin
            X509KeyData := TElXMLKeyInfoX509Data.Create(False);
            X509KeyData.Certificate := Cert;
            Signer.KeyData := X509KeyData;
          end
          else
          begin
            RSAKeyData := TElXMLKeyInfoRSAData.Create(True);
            RSAKeyData.RSAKeyMaterial.Passphrase := frmSign.Passphrase;
            X509KeyData := TElXMLKeyInfoX509Data.Create(True);
            PGPKeyData := TElXMLKeyInfoPGPData.Create(True);

            {$ifndef DELPHI_NET}
            F := TFileStream.Create(frmSign.KeyFile, fmOpenRead or fmShareDenyWrite);
            {$else}
            F := FileStream.Create(frmSign.KeyFile, FileMode.Open, FileAccess.Read);
            {$endif}

            try
              RSAKeyData.RSAKeyMaterial.LoadSecret(F);
            except
            end;

            if not RSAKeyData.RSAKeyMaterial.SecretKey then
            begin
              F.Position := 0;
              LoadCertificate(F, frmSign.Passphrase, X509KeyData);
            end;

            if not RSAKeyData.RSAKeyMaterial.PublicKey and
               not Assigned(X509KeyData.Certificate) then
            begin
              F.Position := 0;
              PGPKeyData.SecretKey := TElPGPSecretKey.Create;
              PGPKeyData.SecretKey.Passphrase := frmSign.Passphrase;
              try
                PGPKeyData.SecretKey.LoadFromStream(F);
              except
                PGPKeyData.SecretKey.Free;
                PGPKeyData.SecretKey := nil;
              end;
            end;

            FreeAndNil(F);

            if RSAKeyData.RSAKeyMaterial.SecretKey then
              Signer.KeyData := RSAKeyData
            else
            if Assigned(X509KeyData.Certificate) then
              Signer.KeyData := X509KeyData
            else
            if Assigned(PGPKeyData.SecretKey) then
              Signer.KeyData := PGPKeyData
            else
              raise EXMLError.Create('Key not loaded.');
          end;
        end;

        if frmXAdES.XAdESEnabled then
        begin
          XAdESSigner := TElXAdESSigner.Create(nil);
          Signer.XAdESProcessor := XAdESSigner;

          XAdESSigner.PolicyId.SigPolicyId.Description := frmXAdES.edDescription.Text;
          if frmXAdES.edDocumentationReference.Text <> '' then
            XAdESSigner.PolicyId.SigPolicyId.DocumentationReferences.Add(frmXAdES.edDocumentationReference.Text);
          XAdESSigner.PolicyId.SigPolicyId.Identifier := frmXAdES.edIdentifier.Text;
          XAdESSigner.PolicyId.SigPolicyId.IdentifierQualifier := frmXAdES.edIdentifierQualifier.Text;

          if frmXAdES.cbProductionPlace.Checked then
          begin
            XAdESSigner.Included := [xipProductionPlace];
            XAdESSigner.ProductionPlace.City := frmXAdES.edCity.Text;
            XAdESSigner.ProductionPlace.StateOrProvince := frmXAdES.edStateOrProvince.Text;
            XAdESSigner.ProductionPlace.PostalCode := frmXAdES.edPostalCode.Text;
            XAdESSigner.ProductionPlace.CountryName := frmXAdES.edCountry.Text;
          end;

          if frmXAdES.cbTimestamp.Checked then
          begin
            TSPClient := TElHTTPTSPClient.Create(nil);
            HTTPClient := TElHTTPSClient.Create(nil);
            TSPClient.HttpClient := HTTPClient;
            TSPClient.URL := frmXAdES.edTimestampServer.Text;
            TSPClient.HashAlgorithm := SB_ALGORITHM_DGST_SHA1;
            XAdESSigner.TSPClient := TSPClient;
            XAdESSigner.IgnoreTimestampFailure := False;
          end;

          XAdESSigner.SigningCertificates := frmXAdES.CertStorage;

          // create XAdESSigner.QualifyingProperties
          XAdESSigner.Generate;
        end;

        Signer.UpdateReferencesDigest;

        if Signer.SignatureType = xstDetached then
        begin
          Signer.Sign;

          FreeAndNil(FXMLDocument);
          try
            SigNode := nil;
            Signer.Save(SigNode);
            FXMLDocument := SigNode.OwnerDocument;
          except
            on E: Exception do
            begin
              FXMLDocument := TElXMLDOMDocument.Create;
              raise EXMLError.CreateFmt('Signed data saving failed. (%s)', [E.Message]);
            end;
          end;
        end
        else
        begin
          if not Assigned(tvXML.Selected) or
             not Assigned(tvXML.Selected.Data) then
          begin
            MessageDlg('Please, select node for signing.', mtInformation, [mbOK], 0);
            Exit;
          end;

          Signer.Sign;

          SigNode := TElXMLDOMNode(tvXML.Selected.Data);
          if SigNode is TElXMLDOMDocument then
            SigNode := TElXMLDOMDocument(SigNode).DocumentElement;

          try
            // If the signature type is enveloping, then the signature is placed into the passed node and the contents of the node are moved to inside of the signature. 
            // If the signature type is enveloped, the signature is placed as a child of the passed node.
            Signer.Save(SigNode);
          except
            on E: Exception do
              raise EXMLError.CreateFmt('Signed data saving failed. (%s)', [E.Message]);
          end;
        end;

        UpdateXML;
      finally
        FreeAndNil(Signer);
        FreeAndNil(XAdESSigner);
        FreeAndNil(TSPClient);
        FreeAndNil(HTTPClient);
        FreeAndNil(HMACKeyData);
        FreeAndNil(RSAKeyData);
        FreeAndNil(X509KeyData);
        FreeAndNil(PGPKeyData);
      end;
    end;
  finally
    FreeAndNil(Refs);
  end;
end;

procedure TfrmMain.btnVerifyClick(Sender: TObject);
var
  Verifier: TElXMLVerifier;
  XAdESVerifier: TElXAdESVerifier;
  HMACKeyData: TElXMLKeyInfoHMACData;
  RSAKeyData: TElXMLKeyInfoRSAData;
  X509KeyData: TElXMLKeyInfoX509Data;
  PGPKeyData: TElXMLKeyInfoPGPData;
  Cert: TElX509Certificate;
  F: {$ifndef DELPHI_NET}TFileStream{$else}FileStream{$endif};
  Buf: ByteArray;
  Node, T: TElXMLDOMNode;
  Ref: TElXMLReference;
  s: XMLString;
  i: Integer;
  SigOK: Boolean;
begin
  if Assigned(tvXML.Selected) and
     Assigned(tvXML.Selected.Data) then
    Node := TElXMLDOMNode(tvXML.Selected.Data)
  else
    Node := TElXMLDOMNode(FXMLDocument);

  // go up by tree and check if user selected element from Signature
  T := Node;
  while (T is TElXMLDOMElement) and
        (TElXMLDOMElement(T).LocalName <> 'Signature') and
        Assigned(T.ParentNode) do
    T := T.ParentNode;

  if not (T is TElXMLDOMDocument) then
    Node := T;

  if Node is TElXMLDOMDocument then
    T := TElXMLDOMDocument(Node).DocumentElement
  else
    T := Node;

  if not (T is TElXMLDOMElement) or
     ((TElXMLDOMElement(T).LocalName <> 'Signature') and
     not Assigned(FindElementByName(TElXMLDOMElement(T), 'Signature', xmlSignatureNamespace))) then
  begin
    MessageDlg('Please, select Signature element for verifying.', mtInformation, [mbOK], 0);
    Exit;
  end;

  HMACKeyData := nil;
  RSAKeyData := nil;
  X509KeyData := nil;
  PGPKeyData := nil;
  Verifier := TElXMLVerifier.Create(nil);
  XAdESVerifier := TElXAdESVerifier.Create(nil);
  Verifier.XAdESProcessor := XAdESVerifier;
  try
    try
      Verifier.Load(TElXMLDOMElement(T));
    except
      on E: Exception do
        raise EXMLError.CreateFmt('Signature data loading failed. (%s)', [E.Message]);
    end;

    for i := 0 to Verifier.References.Count - 1 do
    begin
      Ref := Verifier.References.Reference[i];
      if not Assigned(Ref.URINode) then
      begin
        if Ref.URI = '' then
          Ref.URINode := FXMLDocument.DocumentElement
        else
        begin
          try
            s := ExtractIdFromLocalURI(Ref.URI);
            if s <> '' then
              Ref.URINode := FindElementById(FXMLDocument.DocumentElement, s);
          except
          end;
        end;
      end;
    end;

    frmReference.Document := FXMLDocument;
    frmReferences.References := Verifier.References;
    frmReferences.Verify := True;
    frmSign.cbIncludeKey.Enabled := False;

    if Assigned(XAdESVerifier) and Assigned(XAdESVerifier.QualifyingProperties) then
    begin
      frmXAdES.Verify := True;
      frmXAdES.cbXAdES.Checked := True;

      if Assigned(XAdESVerifier.PolicyId) then
      begin
        frmXAdES.edDescription.Text := XAdESVerifier.PolicyId.SigPolicyId.Description;
        frmXAdES.edDocumentationReference.Text := XAdESVerifier.PolicyId.SigPolicyId.DocumentationReferences.Text;
        frmXAdES.edIdentifier.Text := XAdESVerifier.PolicyId.SigPolicyId.Identifier;
        frmXAdES.edIdentifierQualifier.Text := XAdESVerifier.PolicyId.SigPolicyId.IdentifierQualifier;
      end
      else
      begin
        frmXAdES.edDescription.Text := '';
        frmXAdES.edDocumentationReference.Text := '';
        frmXAdES.edIdentifier.Text := '';
        frmXAdES.edIdentifierQualifier.Text := '';
      end;

      if xipProductionPlace in XAdESVerifier.Included then
      begin
        frmXAdES.cbProductionPlace.Checked := True;
        frmXAdES.edCountry.Text := XAdESVerifier.ProductionPlace.CountryName;
        frmXAdES.edStateOrProvince.Text := XAdESVerifier.ProductionPlace.StateOrProvince;
        frmXAdES.edPostalCode.Text := XAdESVerifier.ProductionPlace.PostalCode;
        frmXAdES.edCity.Text := XAdESVerifier.ProductionPlace.City;
      end
      else
        frmXAdES.cbProductionPlace.Checked := False;

      frmXAdES.lbSignedTime.Caption := 'Signed Time: ' + DateTimeToStr(XAdESVerifier.SigningTime) + ' UTC';
      if Assigned(XAdESVerifier.Timestamp) then
      begin
        frmXAdES.lbTimestamp.Caption := 'Timestamp: ' + DateTimeToStr(XAdESVerifier.Timestamp.Time) + ' UTC';
        frmXAdES.lbTimestampSerial.Caption := 'Timestamp Serial: ' +
          BeautifyBinaryString(BinaryToString(XAdESVerifier.Timestamp.SerialNumber, Length(XAdESVerifier.Timestamp.SerialNumber)), ':');
      end
      else
      begin
        frmXAdES.lbTimestamp.Caption := '';
        frmXAdES.lbTimestampSerial.Caption := '';
      end;

      frmXAdES.CertIDs := XAdESVerifier.QualifyingProperties.SignedProperties.SignedSignatureProperties.SigningCertificate;
    end;

    SigOK := True;

    if not Verifier.ValidateSignature then
    begin
      // KeyInfo doesn't contain correct public key for the signature
      // or data corrupted

      frmSign.CanonicalizationMethod := Verifier.CanonicalizationMethod;
//      frmSign.SignatureType := Verifier.SignatureType;
      frmSign.cmbSignatureType.Text := '';
      frmSign.SignatureMethodType := Verifier.SignatureMethodType;
      frmSign.SigMethod := Verifier.SignatureMethod;
      frmSign.HMACMethod := Verifier.MACMethod;
      frmSign.KeyName := Verifier.KeyName;

      Cert := frmSelWinCert.Certificate;

      if frmSign.ShowModal = mrOK then
      begin
        if Verifier.SignatureMethodType = xmtMAC then
        begin
          HMACKeyData := TElXMLKeyInfoHMACData.Create(True);

          {$ifndef DELPHI_NET}
          F := TFileStream.Create(frmSign.KeyFile, fmOpenRead or fmShareDenyWrite);
          {$else}
          F := FileStream.Create(frmSign.KeyFile, FileMode.Open, FileAccess.Read);
          {$endif}

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?