[xmlsec] need help with the xmlsec library source code

Derek Lei Liu leiliu98@yahoo.com
Wed, 8 Jan 2003 01:54:34 -0800 (PST)


--0-1569752403-1042019674=:44726
Content-Type: text/plain; charset=us-ascii
Content-Disposition: inline

Hi Aleksey,

My program can get an xml message signed and then I
can manually verify the signed message by using xmlsec
utility.  However, the message can't be verified by
the intended receiver program.  The receiver is no
problem since it works fine for other sender programs
that developed by multiple other parties.  

The receiver program is able to verify the
DigestValue. It failed at verifying the signature.  It
seems there is a format mismatch somewhere. So, I
tried to get the exact SignedInfo section right before
it get digested and signed.  I looked into the source
code of xmlsec library and located the
xmlSecSignedInfoCalculate function.  However, I got
lost in the function.  I am having difficulty to
understand the data structures that used.  Anyways, is
it possible that you point it out for me how I can get
the exact SignedInfo string before digested and
signed?

Also, I have attached the source code of my program. 
In the program, I use cleanup_crlf() to remove the
"\n"s that attached from xmlDocDumpMemoryEnc() call. 
I am not sure why this function get extra "\n", but if
I dont' clean them up, even my xmlsec utility
complains.  

If not much hassle, could you take a quick look at my
code snip and see if there is something wrong?

As always, thanks for your great help 

Derek

__________________________________________________
Do you Yahoo!?
Yahoo! Mail Plus - Powerful. Affordable. Sign up now.
http://mailplus.yahoo.com
--0-1569752403-1042019674=:44726
Content-Type: text/plain; name="test.c"
Content-Description: test.c
Content-Disposition: inline; filename="test.c"

void cleanup_crlf(char *str) {
  int i=0, j = 0;

  while (str[j] != '\0') {
    if (str[j] == '\n') {
      j++;
      continue;
    }
    str[i] = str[j];
    i++;
    j++;
  }

  str[i]='\0';
}

/* xml sign msg_in and get msg_out */
int xml_sign(char *msg_in, char *msg_out)
{
    xmlSecKeysMngrPtr keysMngr = NULL;
    xmlSecDSigCtxPtr dsigCtx = NULL;
    xmlDocPtr doc = NULL;
    xmlSecDSigResultPtr result = NULL;

    xmlChar* string;
    xmlNodePtr node;
    int ret = -1;
    int rnd_seed = 0;
    int len;


    /**
     * Init OpenSSL
     */
    while (RAND_status() != 1) {
        RAND_seed(&rnd_seed, sizeof(rnd_seed));
    }

    /*
     * Init libxml
     */
    xmlInitParser();
    LIBXML_TEST_VERSION

    /*
     * Init xmlsec
     */
    xmlSecInit();

    /**
     * Create Keys managers
     */
    keysMngr = xmlSecSimpleKeysMngrCreate();
    if(keysMngr == NULL) {
        errorlog("Error: failed to create keys manager");
        goto done;
    }

    /**
     * load key
     */
    if(xmlSecSimpleKeysMngrLoadPemKey(keysMngr, 
       "/opt/aacs/etc/signing.key", 
         NULL, NULL, 1) == NULL) {
        errorlog("Error: failed to load signing key from %s", 
                "signing.key");
        goto done;
    }

    /**
     * Create Signature Context
     */
    dsigCtx = xmlSecDSigCtxCreate(keysMngr);
    if(dsigCtx == NULL) {
        errorlog("Error: failed to create dsig context");
        goto done;
    }


    /*
     * build an XML tree from a the file; we need to add default
     * attributes and resolve all character and entities references
     */
    xmlLoadExtDtdDefaultValue = XML_DETECT_IDS | XML_COMPLETE_ATTRS;
    xmlSubstituteEntitiesDefault(1);

    /**
     * Load doc
     */
    doc = xmlParseMemory(msg_in, strlen(msg_in));
    if (doc == NULL) {
        errorlog("unable to parse file \"%s\"\n", msg_in);
        goto done;
    }

    /*
     * Check the document is of the right kind
     */
    if(xmlDocGetRootElement(doc) == NULL) {
        errorlog("empty document for file \"%s\"\n", msg_in);
        goto done;
    }

    /*
     * Add Data to the document
     */
   /*
    Delete this from code, David Cong
   
    if(xmlNewChild(xmlDocGetRootElement(doc), NULL, "Something",
                  "Some important data") == NULL) {
        errorlog("failed to add data\n");
        goto done;
    }
    End of Delete section, David Cong
    */

    /**
     * Sign It!
     */
    node = xmlSecFindNode(xmlDocGetRootElement(doc), BAD_CAST "Signature", 
                    xmlSecDSigNs);
    ret = xmlSecDSigGenerate(dsigCtx, NULL, NULL, node, &result);
    if(ret < 0) {
        errorlog("result failed\n");
        goto done;
    }

    /*
     * Print out result document
     */
    xmlDocDumpMemoryEnc(doc, &string, &len, NULL);
    if(string == NULL) {
        errorlog("failed to dump document to memory\n");
        goto done;
    }

    cleanup_crlf(string);

    /* seems a xmlsec library bug (or libxml library) here.  the dumped string
       somehow has an extra '\n' at the end which breaks whoever need to verify
       the signature */
    if (string[len-1] == '\n') string[len-1] = '\0';
    
    memcpy(msg_out, string, len);
    xmlFree(string);

done:
    /*
     * Cleanup
     */
    if(result != NULL) {
        xmlSecDSigResultDestroy(result);
    }
    if(dsigCtx != NULL) {
        xmlSecDSigCtxDestroy(dsigCtx);
    }
    if(doc != NULL) {
        xmlFreeDoc(doc);
    }

    if(keysMngr != NULL) {
        xmlSecSimpleKeysMngrDestroy(keysMngr);
    }
    xmlSecShutdown();

    /*
     * Shutdown libxml
     */
    xmlCleanupParser();

    /*
     * Shutdown OpenSSL
     */
    RAND_cleanup();
    ERR_clear_error();

    return((ret >= 0) ? 0 : 1);
}

--0-1569752403-1042019674=:44726--