You are on page 1of 10

REPORT fp_pdf_test_10.

* get certification

CLASS cl_fp DEFINITION LOAD.

SELECTION-SCREEN BEGIN OF BLOCK s_files WITH FRAME TITLE text-100.


PARAMETERS: p_pdf TYPE localfile VISIBLE LENGTH 64 OBLIGATORY.
SELECTION-SCREEN END OF BLOCK s_files.
SELECTION-SCREEN BEGIN OF BLOCK s_conn WITH FRAME TITLE text-101.
PARAMETERS: p_dest TYPE rfcdest DEFAULT 'ADS' OBLIGATORY.
SELECTION-SCREEN END OF BLOCK s_conn.

TYPE-POOLS slis.
TYPES: ty_tab TYPE STANDARD TABLE OF raw255,
BEGIN OF l_line,
text TYPE ddtext,
value TYPE fpvalue,
END OF l_line.

FIELD-SYMBOLS <fs> TYPE ANY.


CONSTANTS lc_if_status TYPE seoclskey
VALUE 'IF_FP_PDF_SECURITY_STATUS'.
DATA: l_filetable TYPE filetable,
l_filename_pdf TYPE string,
l_fp TYPE REF TO if_fp,
l_pdfobj TYPE REF TO if_fp_pdf_object,
l_pdf TYPE xstring,
l_fpex TYPE REF TO cx_fp_runtime,
l_status TYPE i,
l_certificate TYPE sfpsignature,
l_layout TYPE slis_layout_alv,
l_field TYPE slis_fieldcat_alv,
l_fieldcat TYPE slis_t_fieldcat_alv,
l_dfies TYPE STANDARD TABLE OF dfies,
l_fies TYPE dfies,
l_output TYPE l_line,
l_outputtable TYPE STANDARD TABLE OF l_line,
l_interface TYPE REF TO cl_oo_interf_components_flat,
l_attr TYPE seoattflat.

AT SELECTION-SCREEN ON VALUE-REQUEST FOR p_pdf.


CALL METHOD cl_gui_frontend_services=>file_open_dialog
EXPORTING
default_extension = 'PDF'
file_filter = cl_gui_frontend_services=>filetype_all
CHANGING
file_table = l_filetable
rc = l_status
EXCEPTIONS
file_open_dialog_failed = 1
cntl_error = 2
error_no_gui = 3
not_supported_by_gui = 4
OTHERS = 5.
IF sy-subrc IS INITIAL AND l_status > 0.
READ TABLE l_filetable INTO p_pdf INDEX 1.
ENDIF.

START-OF-SELECTION.
* Load the file from the frontend.
l_filename_pdf = p_pdf.

PERFORM load_file USING l_filename_pdf


CHANGING l_pdf.

* get FP reference
l_fp = cl_fp=>get_reference( ).

TRY.
* create PDF Object
l_pdfobj = l_fp->create_pdf_object( connection = p_dest ).

* set document
CALL METHOD l_pdfobj->set_document
EXPORTING
pdfdata = l_pdf.

* set certification
CALL METHOD l_pdfobj->set_task_getcertification( ).

* execute, call ADS


CALL METHOD l_pdfobj->execute( ).

* get result
CALL METHOD l_pdfobj->get_certification
IMPORTING
status = l_status
certificate = l_certificate.

CATCH cx_fp_runtime_internal INTO l_fpex.


PERFORM error USING l_fpex 'INTERNAL ERROR'.
CATCH cx_fp_runtime_system INTO l_fpex.
PERFORM error USING l_fpex 'SYSTEM ERROR'.
CATCH cx_fp_runtime_usage INTO l_fpex.
PERFORM error USING l_fpex 'USAGE ERROR'.
ENDTRY.

* Proceed only if no error occurred.


CHECK l_fpex IS INITIAL.

* Get status-value descriptions.


CREATE OBJECT l_interface
EXPORTING
clskey = lc_if_status.

* Set output-layout options.


l_layout-colwidth_optimize = 'X'.

l_field-fieldname = 'TEXT'.
l_field-key = 'X'.
l_field-rollname = 'DDTEXT'.
l_field-outputlen = 60.
INSERT l_field INTO TABLE l_fieldcat.
l_field-fieldname = 'VALUE'.
l_field-key = space.
l_field-rollname = 'FPVALUE'.
l_field-outputlen = 132.
INSERT l_field INTO TABLE l_fieldcat.
* Build output table.
CALL FUNCTION 'DDIF_FIELDINFO_GET'
EXPORTING
tabname = 'SFPSIGNATURE'
all_types = 'X'
TABLES
dfies_tab = l_dfies.
LOOP AT l_dfies INTO l_fies WHERE fieldname <> 'CERTIFICATELIST'.
l_output-text = l_fies-fieldtext.
ASSIGN COMPONENT l_fies-fieldname OF STRUCTURE l_certificate
TO <fs>.
IF l_fies-fieldname = 'STATUS'.
WRITE <fs> TO l_attr-attvalue LEFT-JUSTIFIED.
READ TABLE l_interface->attributes
WITH KEY attvalue = l_attr-attvalue
INTO l_attr.
MOVE l_attr-descript TO l_output-value.
ELSE.
l_output-value = <fs>.
ENDIF.
INSERT l_output INTO TABLE l_outputtable.
ENDLOOP.

* Show the received information about the certification.


CALL FUNCTION 'REUSE_ALV_GRID_DISPLAY'
EXPORTING
is_layout = l_layout
it_fieldcat = l_fieldcat
TABLES
t_outtab = l_outputtable.

ZSSF_TEST_PSE
fm READ_KERNEL
L_KERN_REL 742_REL
L_KERN_DBLIB SQL_Server_9.00
L_KERN_PATCHLEVEL 28
Digital signature - Phase1 :
New : Digitally Signed Documents

�Document content�
Sign Verify
CA Trust
Internet
(Register)
Private key Publickey
� Document unchanged � Identity of the signer � Legal certainty
Digital signature - Phase2:
Secure Store & Forward (SSF) Interface

===================
ZDS_BOOKING_EXAMPLE
DSIG_BOOKING_EX PRG sap c_sign cl_ds_runtime prg SSF01 documents: FP_PDF_TEST_07.
I will use it as a base for my
ZSSF_TEST_PSE PRG tcodes STRUST
add new application code to table SSFAPPLIC and then you can use transaction SSFA
to configure it.
hashing algorithm (in your case SHA1) or PSE location.

DS_AUTHORITY
he digital signature for approval of the documents uploaded in the SOLAR01/SOLAR02.

===================

you are lucky guy. ABAP AS has limited support for crypto. Basically, it supports
only PKCS#7. Fortunately, that's what you need.

Anyway, all stuff is performed within kernel but there are ABAP function modules
which call C routines.
You need to look for FMs with name like SSF_*. As Julius mentioned there is a nice
documentation for this API.
Basically, the easiest way is to use FM SSFV_KRN_ENVELOPE.
It has a simple interface, you pass application ID and string of bytes.
You need to manually add new application code to table SSFAPPLIC and then you can
use transaction SSFA to configure it.
Here you need can define additional parameters like hashing algorithm (in your case
SHA1) or PSE location.
Your new application will use separate certificate which you need to import using
transaction STRUST.
Your client has already given you public key which you need to use for encryption.
Just import .cer file into corresponding PSE. For this scenario you don't need a
private key.

FM (SSF_SIGN or SSF_KRN_SIGN). So you need to sign it with your private key and
then encrypt with public key of receiving system. The receiving system will decrypt
it first using its private key and then verify signature using public key of SAP
system. What certificate you are going to use for signing is up to you. You would
have to just distribute public key to receiving system.

K, now I'm stuck. I'll give you a list of all the things (files, keys,
certificates...) I have, and what I need to do.

Version of SAP 4.7 with SAP_BASIS and SAP_ABA Release 620.

Requirement:
1.- Sign an output file for payments with SHA1withRSA.
2.- Envelope with PKCS#7.
3.- This must be done in background mode, so the user doesn't interact with the
signing. So I need to perform this in the application server. The problematic of
including this on an exit, it's not a big deal, so i only wanted to create some
test programs in the first place.

The customer gave to me in order to perform this, the followings files:


1.- File "AAAA.cer" from the receiver, in order to envelope the output file. This I
think is the public key of the receiver.
2.- Files "BBBB.crt", "BBBB.key" and "CCCC.pem" from the customer,
in order to sign the output file. This seems to be the private key of the customer.

Now, the questions I have are:


1.- Is there anything missing to perform the encrypt and the file signing?
2.- Do I have to use STRUST, and How? I have already used it, but i think that in
the wrong way. Do I have to create 2 PSE files, one for the signing and another for
the encrypting?
3.- I read the help.sap, and found in some cases that the SAPSECULIB only works for
signing, and not for encrypting. To Encrypt, do I need to install SAP Cryptographic
Library?
4.- I cannot run report SSF01 succesfully.
5.- Do I Have to create a SSF Profile?

I'll really appreciate your help. I have been working with abap, since 2005, but
this is driving me crazy.

Merry christmas for everyone who read my threads!


====================
Create a Digital Signature in ABAP ( Sample Code)

This is a short list of necessary operations:


Build a table for metadata using as key a field referring to data element
SIGN_GUID_22 and the complete key for your to-be-signed document; in my case:
ZZAPT_SIGNATURE
FIELD DATA ELEMENT
MANDT
MANDT
SIGN_ID SIGN_GUID_22
CORDERID N1CORDID
Build a structure for operation log: ZZAPT_SIGNATURE_LOG
FIELD DATA ELEMENT
.include
SIGN_PROT_STRUC
CORDERID N1CORDID
Launch the following transactions(very intuitive):
SLG0: declare a sub-object under CDSG1
SIGNA:declare your application
SIGNO:insert the signature object
ELSIG03N: choose and link the type of signature(in my case R/3)
REPORT ZPR00004
.
DATA: lo_ds_runtime TYPE REF TO if_ds_runtime.
DATA: lo_sign TYPE REF TO if_ds_sign.
DATA: l_metadata_wa TYPE ZZAPT_SIGNATURE. lo_ds_runtime =
cl_ds_runtime=>get_instance( ).
l_metadata_wa-corderid = '5159DB46ACFC1424E1000000010000AB'."Doc ID call method
lo_ds_runtime->create
exporting
im_appl = 'ZTEST'"APPL
im_object = 'ZTEST'"OBJECT
im_meta = l_metadata_wa
im_type = 'C' "Synch signature
receiving
result = lo_sign.
call method lo_sign->sign
exporting
im_signer = sy-uname
im_doc_txt = 'SIGNING DOCUMENT 5159DB46ACFC1424E1000000010000AB'
im_doctype = 'TXT'. commit work and wait.

======================

Easy Authorization Management for SAP

C_SIGN - Authorization for Digital Signature


RFUMSV00 - Advance Return for Tax on Sales/Purchases ROGBILLS - Synchronize
billing plans
This documentation is copyright by SAP AG.

Definition
You use this authorization object to restrict the authorization for executing
digital signatures, depending on the application and the signature object.
The authorization check for executing digital signatures is dependent on the
implementation of the DS_AUTHORITY BAdI. If no specific application authorization
check is implemented in the AUTHORITY_CHECK BADI method, a check is made for the
authorization object defined here.
The C_SIGN authorization object is only valid for implementations of the digital
signature with the CL_DS_RUNTIME class.
Defined fields
The authorization object contains the following fields:
SIGNAPPL - Digital signature application
SIGNOBJ - Digital signature object
ACTVT - Activity
(03) Display - Controls the authorization to display the digital signature log

(06) Delete - Controls the authorization to delete signature process data after
successful archiving

(24) Archive - Controls the authorization to archive signature process data

(73) Execute digital signature - Controls the authorization to execute the digital
signature

Easy Authorization Management for SAP

Addresses (Business Address Services) ROGBILLS - Synchronize billing plans


This documentation is copyright by SAP AG.

Length: 1820 Date: 20190212 Time: 065926 sap01-206 ( 46 ms )

=============================================================================

report fp_pdf_test_07.
* set signature
class cl_fp definition load.

selection-screen begin of block s_files with frame title text-100.


parameters: p_pdf(64) type c lower case obligatory,
p_out(64) type c lower case obligatory.
selection-screen end of block s_files.
selection-screen begin of block s_conn with frame title text-101.
parameters: p_dest type rfcdest default 'ADS' obligatory.
selection-screen end of block s_conn.
selection-screen begin of block s_sig with frame title text-102.
parameters: s_key(64) type c lower case,
s_field(64) type c lower case,
s_reason(64) type c lower case,
s_loc(64) type c lower case,
s_cinfo(64) type c lower case.
selection-screen end of block s_sig.

types: ty_raw(255) type x,


ty_tab type standard table of ty_raw.

data: l_filename_pdf type string,


l_filename_out type string,
l_fp type ref to if_fp,
l_pdfobj type ref to if_fp_pdf_object,
l_pdf type xstring,
l_out type xstring,
l_fpex type ref to cx_fp_runtime.

l_filename_pdf = p_pdf.
l_filename_out = p_out.

perform load_file using l_filename_pdf


changing l_pdf.

* get FP reference
l_fp = cl_fp=>get_reference( ).

try.
* create PDF Object
l_pdfobj = l_fp->create_pdf_object( connection = p_dest ).

* set document
call method l_pdfobj->set_document
exporting
pdfdata = l_pdf.

* set signature
call method l_pdfobj->set_signature
exporting
keyname = s_key
fieldname = s_field
reason = s_reason
location = s_loc
contactinfo = s_cinfo.

* execute, call ADS


call method l_pdfobj->execute( ).

* get result -> l_out


call method l_pdfobj->get_document
importing
pdfdata = l_out.

catch cx_fp_runtime_internal into l_fpex.


perform error using l_fpex 'INTERNAL ERROR'.
catch cx_fp_runtime_system into l_fpex.
perform error using l_fpex 'SYSTEM ERROR'.
catch cx_fp_runtime_usage into l_fpex.
perform error using l_fpex 'USAGE ERROR'.
endtry.

check l_fpex is initial.

* download PDF
data: l_len type i,
l_tab type tsfixml.

call function 'SCMS_XSTRING_TO_BINARY'


exporting
buffer = l_out
importing
output_length = l_len
tables
binary_tab = l_tab.
call method cl_gui_frontend_services=>gui_download
exporting
bin_filesize = l_len
filename = l_filename_out
filetype = 'BIN'
changing
data_tab = l_tab
exceptions
others = 1.
if sy-subrc = 0.
write:/ 'Datei erfolgreich geschrieben'(001).
else.
write:/ 'Fehler beim Schreiben der Datei'(002).
endif.

form error using p_fpex type ref to cx_fp_runtime


p_str type string.
data: l_errcode type i,
l_errmsg type string,
l_string type string.

write:/ '***************************************************'.
write:/ '***', p_str.
write:/ '***************************************************'.
skip 2.

call method p_fpex->get_errall


importing
errcode = l_errcode
errmsg = l_errmsg.

write:/ 'ERROR CODE : ', l_errcode.


write:/ 'ERROR MESSAGE : ', l_errmsg.
l_string = p_fpex->get_text( ).
write:/ l_string.

endform.

form load_file using p_filename type string


changing p_content type xstring.
data: l_rawtab type ty_tab,
l_len type i.

call method cl_gui_frontend_services=>gui_upload


exporting
filename = p_filename
filetype = 'BIN'
importing
filelength = l_len
changing
data_tab = l_rawtab
exceptions
file_open_error = 1
file_read_error = 2
no_batch = 3
gui_refuse_filetransfer = 4
invalid_type = 5
no_authority = 6
unknown_error = 7
bad_data_format = 8
header_not_allowed = 9
separator_not_allowed = 10
header_too_long = 11
unknown_dp_error = 12
access_denied = 13
dp_out_of_memory = 14
disk_full = 15
dp_timeout = 16
not_supported_by_gui = 17
error_no_gui = 18
others = 19.
if sy-subrc <> 0.
message id sy-msgid type sy-msgty number sy-msgno
with sy-msgv1 sy-msgv2 sy-msgv3 sy-msgv4.
endif.

perform convert_tab_to_x using l_rawtab l_len


changing p_content.

endform.

form convert_tab_to_x using p_rawtab type ty_tab


p_len type i
changing p_xstr type xstring.
data: l_line type ty_raw,
l_count type i,
l_len type i,
l_rest type i.

describe table p_rawtab lines l_count.


loop at p_rawtab into l_line.
if sy-tabix = l_count.
l_rest = p_len - l_len.
concatenate p_xstr l_line(l_rest) into p_xstr in byte mode.
else.
concatenate p_xstr l_line into p_xstr in byte mode.
add 255 to l_len.
endif.
endloop.

endform.

============================================================================