Implementing WS-Security in Progress ABL

Posted by nicolewells.n on 15-Dec-2017 03:46

I'm struggling with implementing WS-Security in Progress ABL.

It seems possible, this knowledgebase: knowledgebase.progress.com/.../P88147 states:

For outgoing WS-Security, create SOAP Headers containing the WS-Security content manually using the OpenEdge Web Service client.
First of all I'm struggling with the creation of a base64 encoded and SHA1 digested password hash.

Password digest according to the WS-Security specification. Source.

Password_Digest = Base64 ( SHA-1 ( nonce + created + password ) ) 

Nonce is a random string of a specific length, could basically be a UUID. The nonce is Base64-encoded (it's sent encoded in the soap header).

Created is a date in the format "YYYY-MM-DDTHH:MM:SS.SSSZ". Milliseconds are optional. Z for GMT should always be set.

Password is a password given out by the web service provider.

Trying to mimic this answer on SO: Working algorithm for PasswordDigest in Splunk Security

PROCEDURE generatePassHash:
    DEFINE INPUT  PARAMETER pcNonce    AS CHARACTER   NO-UNDO.
    DEFINE INPUT  PARAMETER pcCreated  AS CHARACTER   NO-UNDO.
    DEFINE INPUT  PARAMETER pcPassword AS CHARACTER   NO-UNDO.

    DEFINE OUTPUT PARAMETER pcHash     AS CHARACTER   NO-UNDO.

    DEFINE VARIABLE mBytes        AS MEMPTR      NO-UNDO.
    DEFINE VARIABLE cNonceDecoded AS CHARACTER   NO-UNDO.

    /* Base64-decode the nonce since it's in encoded format */
    ASSIGN 
        cNonceDecoded = STRING(BASE64-DECODE(pcNonce)).

    /* Set size of mempointer */
    SET-SIZE(mBytes) = LENGTH(cNonceDecoded) + LENGTH(pcCreated) + LENGTH(pcPassword) + 1.

    /* Put the decoded nonce first */
    PUT-STRING(mBytes, 1) = cNonceDecoded.

    /* Add create time */
    PUT-STRING(mBytes, 1 + LENGTH(cNonceDecoded)) = pcCreated.

    /* Add password */
    PUT-STRING(mBytes, 1 + LENGTH(cNonceDecoded) + LENGTH(pcCreated)) = pcPassword.

    /* Create out-data */
    pcHash = STRING(BASE64-ENCODE(SHA1-DIGEST(mBytes))).

    /* Clean up mempointer */
    SET-SIZE(mBytes) = 0.


END PROCEDURE.

DEFINE VARIABLE cNonce       AS CHARACTER   NO-UNDO.
DEFINE VARIABLE cTimeStamp   AS CHARACTER   NO-UNDO.
DEFINE VARIABLE cClearPass   AS CHARACTER   NO-UNDO.
DEFINE VARIABLE cRightAnswer AS CHARACTER   NO-UNDO.

ASSIGN
    cNonce       = "UIYifr1SPoNlrmmKGSVOug=="
    cTimeStamp   = "2009-12-03T16:14:49Z"
    cClearPass   = "test8"
    cRightAnswer = "yf2yatQzoaNaC8BflCMatVch/B8=".

RUN generatePassHash(cNonce, cTimeStamp, cClearPass, OUTPUT cHash).

MESSAGE "Is:" SKIP cHash SKIP(2)
    "Should be:" SKIP
    cRightAnswer
    VIEW-AS ALERT-BOX INFORMATION TITLE "OK?".

I'm guessing that this might have to do with either me messing up the mempointer handling or the fact that everything should be UTF-8?

NB

I can easily produce the same erroneous hash as mentioned in the referenced question above with this simple code:

MESSAGE STRING(BASE64-ENCODE(SHA1-DIGEST("UIYifr1SPoNlrmmKGSVOug==" + "2009-12-03T16:14:49Z" + "test8"))) VIEW-AS ALERT-BOX

Help me on this thanks.

All Replies

This thread is closed