Skip to Content

RG2485 - UDF LookUpTokenSign TimeZone error on AEX 7.4

We are on a PI 7.4 single stack AEX.

There is an error in the UDF LookUpTokenSign for the Electronic Invoice for Argentina SAP solucion, that gets the authorization by validating certificates.

The error we are receiving by the WS is that the date/time of the request is either in the future or the past:

AFIP error: generationTime posee formato o dato inválido (ej: en el futuro o más de 24 horas de antigüedad)

We have found in the XPI_MONITOR log that one step is using a parameter with the date/time 3 hours in advance as if it were not considering the Argentina GMT-03 timezone.

Server date/time is ok and in sync with a timezone external entity. All logs in message monitor, etc are correct but the one indicated in the XPI_MONITOR

Find attachment with the XPI_MONITOR details. Look for the fifth line at time 17:48:29:973. There you can see the parameter TimeSent=2016-11-02T20:48:29Z.

This is what the line in question contains:

⇨ with {ReceiverParty=, ReceiverSystem=BC_AFIP, Interface=BAPI_AR_WS_CONN_TEST, SenderService=ED0201, ConversationId=null, InterfaceNamespace=urn:sap-com:document:sap:rfc:functions, SenderSystem=ED0201, ReceiverNamespace=http://sap.com/xi/CNT-LOC/AR_RG2485_wsfev1, MessageId=b5fac49da13d11e6cdf000000026094e, VersionMinor=1, SenderParty=, ProcessingMode=synchronous, VersionMajor=7, MappingTrace=, ReceiverService=BC_AFIP, TimeSent=2016-11-02T20:48:29Z, RefToMessageId=null, ContentType=application/xml, ReceiverName=SI_IS_FEDummy}

I don´t know where this is coming from, if it is related to a general configuration or to the UDF itself.

I appreciate any help

Thanks,

Add comment
10|10000 characters needed characters exceeded

  • Get RSS Feed

3 Answers

  • Best Answer
    Nov 04, 2016 at 12:00 AM

    Note: 1558532

    File "PI_Additional_Setup_guide.zip", extract it and you will see a magic file with the name "wsaaClass.jar", so if you decompile it with an online tool like javadecompilers, you can see everything that happens behind the scenes...( These methods are used in mapping "MM_Request_FEDummy" inside of UDF "LookUpTokenSign").

    Enjoy it!.

    wsaaClass.java:

    /*
     * Decompiled with CFR 0_118.
     * 
     * Could not load the following classes:
     *  com.sap.aii.mapping.api.AbstractTrace
     *  com.sap.aii.mapping.lookup.Channel
     *  com.sap.aii.mapping.lookup.LookupException
     *  com.sap.aii.mapping.lookup.LookupService
     *  com.sap.aii.mapping.lookup.Payload
     *  com.sap.aii.mapping.lookup.RfcAccessor
     *  com.sap.aii.mapping.lookup.SystemAccessor
     *  com.sap.aii.mapping.lookup.XmlPayload
     *  com.sap.engine.interfaces.keystore.KeystoreManager
     *  com.sap.security.api.ssf.ISsfProfile
     *  com.sap.security.core.server.ssf.SsfDataPKCS7
     *  com.sap.security.core.server.ssf.SsfInvalidKeyException
     *  com.sap.security.core.server.ssf.SsfProfileKeyStore
     *  com.sap.security.core.util.Base64
     */
    package wsaaPackage;
    
    import com.sap.aii.mapping.api.AbstractTrace;
    import com.sap.aii.mapping.lookup.Channel;
    import com.sap.aii.mapping.lookup.LookupException;
    import com.sap.aii.mapping.lookup.LookupService;
    import com.sap.aii.mapping.lookup.Payload;
    import com.sap.aii.mapping.lookup.RfcAccessor;
    import com.sap.aii.mapping.lookup.SystemAccessor;
    import com.sap.aii.mapping.lookup.XmlPayload;
    import com.sap.engine.interfaces.keystore.KeystoreManager;
    import com.sap.security.api.ssf.ISsfProfile;
    import com.sap.security.core.server.ssf.SsfDataPKCS7;
    import com.sap.security.core.server.ssf.SsfInvalidKeyException;
    import com.sap.security.core.server.ssf.SsfProfileKeyStore;
    import com.sap.security.core.util.Base64;
    import com.sun.org.apache.xerces.internal.jaxp.datatype.XMLGregorianCalendarImpl;
    import java.io.ByteArrayInputStream;
    import java.io.ByteArrayOutputStream;
    import java.io.IOException;
    import java.io.InputStream;
    import java.rmi.RemoteException;
    import java.security.KeyStore;
    import java.util.Date;
    import java.util.GregorianCalendar;
    import java.util.TimeZone;
    import javax.naming.InitialContext;
    import javax.xml.parsers.DocumentBuilder;
    import javax.xml.parsers.DocumentBuilderFactory;
    import org.w3c.dom.Document;
    import org.w3c.dom.Node;
    import org.w3c.dom.NodeList;
    
    public class wsaaClass {
        public static String create_LoginTicketRequestXML(String service, AbstractTrace trace) {
            long TicketTime = 43200000;
            String LoginTicketRequest_xml = null;
            Date GenTime = new Date();
            GregorianCalendar gentime = new GregorianCalendar(TimeZone.getTimeZone("GMT-3"));
            GregorianCalendar exptime = new GregorianCalendar(TimeZone.getTimeZone("GMT-3"));
            String UniqueId = new Long(GenTime.getTime() / 1000).toString();
            exptime.setTime(new Date(GenTime.getTime() + TicketTime));
            XMLGregorianCalendarImpl XMLGenTime = new XMLGregorianCalendarImpl(gentime);
            XMLGregorianCalendarImpl XMLExpTime = new XMLGregorianCalendarImpl(exptime);
            LoginTicketRequest_xml = "<?xml version=\"1.0\" encoding=\"UTF-8\" standalone=\"yes\"?><loginTicketRequest version=\"1.0\"><header><uniqueId>" + UniqueId + "</uniqueId>" + "<generationTime>" + XMLGenTime + "</generationTime>" + "<expirationTime>" + XMLExpTime + "</expirationTime>" + "</header>" + "<service>" + service + "</service>" + "</loginTicketRequest>";
            trace.addInfo(LoginTicketRequest_xml);
            return LoginTicketRequest_xml;
        }
    
        public static String create_cms(String loginTicketRequestXML, String keyStorageView, String keyStorageEntry, AbstractTrace trace) {
            KeyStore keyStore = null;
            SsfProfileKeyStore profile = null;
            boolean res = false;
            ByteArrayInputStream is = null;
            SsfDataPKCS7 data = null;
            String CMS = null;
            try {
                is = new ByteArrayInputStream(loginTicketRequestXML.getBytes("UTF-8"));
                data = new SsfDataPKCS7((InputStream)is);
                trace.addInfo("SsfDataPKCS7 object  Created");
            }
            catch (Exception e) {
                trace.addWarning("Error while creating SsfDataPKCS7+e");
            }
            InitialContext ctx = null;
            try {
                ctx = new InitialContext();
                trace.addInfo("InitialContext Object Created");
            }
            catch (Exception e1) {
                trace.addWarning("Error while creating Initial Context" + e1);
            }
            Object o = null;
            try {
                o = ctx.lookup("keystore");
                trace.addInfo("Lookup Keystore");
            }
            catch (Exception e2) {
                trace.addWarning("Error Lookingup Keystore" + e2);
            }
            KeystoreManager manager = (KeystoreManager)o;
            try {
                keyStore = manager.getKeystore(keyStorageView);
                trace.addInfo("keyStorageView Name:" + keyStorageView);
            }
            catch (RemoteException e3) {
                Object KeyStorageView = null;
                trace.addWarning("keyStorageView Error:" + e3);
            }
            String alias = keyStorageEntry;
            try {
                profile = new SsfProfileKeyStore(keyStore, alias, null);
                trace.addInfo("Accessing keystore Entry");
            }
            catch (Exception e) {
                throw new SecurityException("Error while accessing keystore Entry: " + e);
            }
            try {
                res = data.sign((ISsfProfile)profile);
            }
            catch (SsfInvalidKeyException e) {
                trace.addWarning("Error while signing data " + (Object)e);
            }
            if (!res) {
                trace.addWarning("Creation of signature failed");
            }
            try {
                Base64 base64 = new Base64();
                CMS = new String(Base64.encode((byte[])data.getDataPKCS7()));
            }
            catch (Exception e) {
                trace.addWarning("Error while converting into Base64 " + e);
            }
            return CMS;
        }
    
        public static String invoke_wsaa(String businessService_WSAA, String channel_WSAA, String cms, AbstractTrace trace) {
            String loginTicketResponse;
            IOException e2;
            ByteArrayOutputStream out;
            SystemAccessor accessor;
            accessor = null;
            out = null;
            loginTicketResponse = null;
            try {
                try {
                    Channel channel = LookupService.getChannel((String)businessService_WSAA, (String)channel_WSAA);
                    accessor = LookupService.getSystemAccessor((Channel)channel);
                    String SOAPxml = "<loginCms xmlns:m=\"http://wsaa.view.sua.dvadac.desein.afip.gov\"><in0>" + cms + "</in0></loginCms>";
                    ByteArrayInputStream inputStream = new ByteArrayInputStream(SOAPxml.getBytes());
                    trace.addInfo(SOAPxml);
                    XmlPayload payload = LookupService.getXmlPayload((InputStream)inputStream);
                    Payload SOAPOutPayload = null;
                    SOAPOutPayload = accessor.call((Payload)payload);
                    InputStream loginCmsResponse = SOAPOutPayload.getContent();
                    DocumentBuilderFactory factory = DocumentBuilderFactory.newInstance();
                    DocumentBuilder builder = factory.newDocumentBuilder();
                    Document document = builder.parse(loginCmsResponse);
                    NodeList nl = document.getElementsByTagName("ns1:loginCmsReturn");
                    int num = nl.getLength();
                    if (num >= 1) {
                        loginTicketResponse = nl.item(0).getFirstChild().getNodeValue();
                    }
                }
                catch (Exception e) {
                    trace.addWarning("Error while lookup " + e.getMessage());
                }
            }
            catch (Throwable var19_19) {
                IOException e2;
                Object var18_20 = null;
                if (out != null) {
                    try {
                        out.close();
                    }
                    catch (IOException e2) {
                        trace.addWarning("Error while closing stream " + e2.getMessage());
                    }
                }
                if (accessor != null) {
                    try {
                        accessor.close();
                    }
                    catch (LookupException e2) {
                        trace.addWarning("Error while closing accessor " + e2.getMessage());
                    }
                }
                throw var19_19;
            }
            Object var18_21 = null;
            if (out != null) {
                try {
                    out.close();
                }
                catch (IOException e2) {
                    trace.addWarning("Error while closing stream " + e2.getMessage());
                }
            }
            if (accessor != null) {
                try {
                    accessor.close();
                }
                catch (LookupException e2) {
                    trace.addWarning("Error while closing accessor " + e2.getMessage());
                }
            }
            return loginTicketResponse;
        }
    
        public static String rfcLookUpTokenSign(String businessService_RFC, String channel_RFC, String CUIT_COMP_CODE, String service, AbstractTrace trace) {
            IOException e2;
            int addTwoMins = 120000;
            String xmlRFCResult = null;
            Date GenTime = new Date();
            GregorianCalendar gentime = new GregorianCalendar(TimeZone.getTimeZone("GMT-3"));
            gentime.setTime(new Date(GenTime.getTime() + (long)addTwoMins));
            XMLGregorianCalendarImpl XMLGenTime = new XMLGregorianCalendarImpl(gentime);
            String rfcxml = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ns0:BAPI_AR_WS_LOOKUP_TOKEN_SIGN xmlns:ns0=\"urn:sap-com:document:sap:rfc:functions\"><CUIT_COMP_CODE>" + CUIT_COMP_CODE + "</CUIT_COMP_CODE><WS_SERVICE>" + service + "</WS_SERVICE><GEN_TIME>" + XMLGenTime + "</GEN_TIME></ns0:BAPI_AR_WS_LOOKUP_TOKEN_SIGN>";
            trace.addInfo("XML-RFC Request for BAPI_AR_WS_LOOKUP_TOKEN_SIGN to lookup Token and Sign:" + rfcxml);
            RfcAccessor accessor = null;
            ByteArrayOutputStream out = null;
            try {
                try {
                    Channel channel = LookupService.getChannel((String)businessService_RFC, (String)channel_RFC);
                    accessor = LookupService.getRfcAccessor((Channel)channel);
                    ByteArrayInputStream inputStream = new ByteArrayInputStream(rfcxml.getBytes());
                    XmlPayload payload = LookupService.getXmlPayload((InputStream)inputStream);
                    XmlPayload RFCResultPayload = accessor.call(payload);
                    InputStream isRFCResult = RFCResultPayload.getContent();
                    out = new ByteArrayOutputStream(1024);
                    byte[] buffer = new byte[1024];
                    int read = isRFCResult.read(buffer);
                    while (read > 0) {
                        out.write(buffer, 0, read);
                        read = isRFCResult.read(buffer);
                    }
                    xmlRFCResult = out.toString();
                }
                catch (Exception e) {
                    trace.addWarning("Error while lookup " + e.getMessage());
                }
            }
            catch (Throwable var21_21) {
                IOException e2;
                Object var20_22 = null;
                if (out != null) {
                    try {
                        out.close();
                    }
                    catch (IOException e2) {
                        trace.addWarning("Error while closing stream " + e2.getMessage());
                    }
                }
                if (accessor != null) {
                    try {
                        accessor.close();
                    }
                    catch (LookupException e2) {
                        trace.addWarning("Error while closing accessor " + e2.getMessage());
                    }
                }
                throw var21_21;
            }
            Object var20_23 = null;
            if (out != null) {
                try {
                    out.close();
                }
                catch (IOException e2) {
                    trace.addWarning("Error while closing stream " + e2.getMessage());
                }
            }
            if (accessor != null) {
                try {
                    accessor.close();
                }
                catch (LookupException e2) {
                    trace.addWarning("Error while closing accessor " + e2.getMessage());
                }
            }
            return xmlRFCResult;
        }
    
        /*
         * Enabled force condition propagation
         * Lifted jumps to return sites
         */
        public static void rfcLookupTokenSignUpdate(String businessService_RFC, String channel_RFC, String CUIT_COMP_CODE, String token, String sign, String generationTime, String expirationTime, String service, AbstractTrace trace) {
            String rfcxmlUpdate = "<?xml version=\"1.0\" encoding=\"UTF-8\"?><ns0:BAPI_AR_WS_LOOKUP_TOKEN_SIGN xmlns:ns0=\"urn:sap-com:document:sap:rfc:functions\"><CUIT_COMP_CODE>" + CUIT_COMP_CODE + "</CUIT_COMP_CODE><EXP_TIME>" + expirationTime + "</EXP_TIME><GEN_TIME>" + generationTime + "</GEN_TIME><SIGN>" + sign + "</SIGN><TOKEN>" + token + "</TOKEN><WS_SERVICE>" + service + "</WS_SERVICE></ns0:BAPI_AR_WS_LOOKUP_TOKEN_SIGN>";
            trace.addInfo(rfcxmlUpdate);
            RfcAccessor accessor = null;
            try {
                try {
                    Channel channel = LookupService.getChannel((String)businessService_RFC, (String)channel_RFC);
                    accessor = LookupService.getRfcAccessor((Channel)channel);
                    ByteArrayInputStream inputStream = new ByteArrayInputStream(rfcxmlUpdate.getBytes());
                    XmlPayload payload = LookupService.getXmlPayload((InputStream)inputStream);
                    XmlPayload RFCResultPayload = accessor.call(payload);
                    trace.addInfo("Calling RFC Update");
                }
                catch (Exception e) {
                    trace.addWarning("Error while lookup " + e.getMessage());
                }
            }
            catch (Throwable var16_16) {
                Object var15_17 = null;
                if (accessor == null) throw var16_16;
                try {
                    accessor.close();
                    throw var16_16;
                }
                catch (LookupException e) {
                    trace.addWarning("Error while closing accessor " + e.getMessage());
                }
                throw var16_16;
            }
            Object var15_18 = null;
            if (accessor == null) return;
            try {
                accessor.close();
                return;
            }
            catch (LookupException e) {
                trace.addWarning("Error while closing accessor " + e.getMessage());
            }
        }
    }

    Best Regards.

    Add comment
    10|10000 characters needed characters exceeded

  • Nov 11, 2016 at 03:25 PM

    Thanks Maximiliano, this helped me to deeply understand the issue.

    The issue was with the NTP (network time protocol) as the server clock was not in sync.

    Regards,

    Add comment
    10|10000 characters needed characters exceeded

  • Jul 04, 2017 at 03:41 PM

    Hello Leandro,

    How you have fixed the issue, we are also getting the same error i.e. The expiration time is less than the current time. Can you let us know how you have synch server clock with NTP.

    Thanks, Rakesh Duggal

    Add comment
    10|10000 characters needed characters exceeded