Sisyphus repository
Last update: 1 october 2023 | SRPMs: 18631 | Visits: 37868106
en ru br
ALT Linux repos
S:2.0.0-alt4
5.0: 1.2.1-alt2.1.1
4.1: 1.2.1-alt2.1
4.0: 1.2.1-alt2.1
3.0: 1.1.5-alt4

Group :: Networking/Other
RPM: openslp

 Main   Changelog   Spec   Patches   Sources   Download   Gear   Bugs and FR  Repocop 

Patch: 03_auth.patch
Download


--- common/slp_auth.c
+++ common/slp_auth.c	2003/12/15 17:15:46
@@ -0,0 +1,928 @@
+/***************************************************************************/
+/*                                                                         */
+/* Project:     OpenSLP - OpenSource implementation of Service Location    */
+/*              Protocol                                                   */
+/*                                                                         */
+/* File:        slp_auth.c                                                 */
+/*                                                                         */
+/* Abstract:    Common for OpenSLP's SLPv2 authentication implementation   */
+/*              Currently only bsd 0x0002 (DSA-SHA1) is supported          */
+/*                                                                         */
+/*-------------------------------------------------------------------------*/
+/*                                                                         */
+/*     Please submit patches to http://www.openslp.org                     */
+/*                                                                         */
+/*-------------------------------------------------------------------------*/
+/*                                                                         */
+/* Copyright (C) 2000 Caldera Systems, Inc                                 */
+/* All rights reserved.                                                    */
+/*                                                                         */
+/* Redistribution and use in source and binary forms, with or without      */
+/* modification, are permitted provided that the following conditions are  */
+/* met:                                                                    */ 
+/*                                                                         */
+/*      Redistributions of source code must retain the above copyright     */
+/*      notice, this list of conditions and the following disclaimer.      */
+/*                                                                         */
+/*      Redistributions in binary form must reproduce the above copyright  */
+/*      notice, this list of conditions and the following disclaimer in    */
+/*      the documentation and/or other materials provided with the         */
+/*      distribution.                                                      */
+/*                                                                         */
+/*      Neither the name of Caldera Systems nor the names of its           */
+/*      contributors may be used to endorse or promote products derived    */
+/*      from this software without specific prior written permission.      */
+/*                                                                         */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     */
+/* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT      */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR   */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA      */
+/* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON       */
+/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    */
+/*                                                                         */
+/***************************************************************************/
+
+#include <time.h>
+
+#include "slp_xmalloc.h"
+#include "slp_auth.h"
+#include "slp_crypto.h"
+
+/*-------------------------------------------------------------------------*/
+int SLPAuthDigestString(int spistrlen,
+                        const char* spistr,
+                        int stringlen,
+                        const char* string,
+                        unsigned long timestamp,
+                        unsigned char* digest)
+/*-------------------------------------------------------------------------*/
+{
+    int                 result;
+    int                 tmpbufsize;
+    unsigned char*      tmpbuf;
+    unsigned char*      curpos;
+
+    /* assume success */
+    result = 0;
+
+    /*-------------------------------------------------------*/
+    /* Allocate temporary buffer for contiguous data         */
+    /*-------------------------------------------------------*/
+    /* +8 makes room for:  stringlen (2 bytes)               */
+    /*                     autharray[i].spistrlen (2 bytes)  */
+    /*                     timestamp 4 bytes                 */
+    tmpbufsize = stringlen + spistrlen + 8;
+    tmpbuf = xmalloc(tmpbufsize);
+    if(tmpbuf == 0)
+    {
+        return SLP_ERROR_INTERNAL_ERROR;
+    }
+    
+    /*-----------------------------------*/
+    /* Copy data into continguous buffer */
+    /*-----------------------------------*/
+    curpos = tmpbuf;
+    
+    ToUINT16(curpos,spistrlen);
+    curpos = curpos + 2;
+    memcpy(curpos, spistr, spistrlen);
+    curpos = curpos + spistrlen;
+
+    ToUINT16(curpos,stringlen);
+    curpos = curpos + 2;
+    memcpy(curpos, string, stringlen);
+    curpos = curpos + stringlen; 
+
+    ToUINT32(curpos, timestamp);
+
+    /*---------------------*/
+    /* Generate the digest */
+    /*---------------------*/
+    if(SLPCryptoSHA1Digest(tmpbuf,
+                           tmpbufsize,
+                           digest))
+    {
+        result = SLP_ERROR_INTERNAL_ERROR;
+    }
+
+    /*------------------------------*/
+    /* Cleanup the temporary buffer */
+    /*------------------------------*/
+    xfree(tmpbuf);
+
+    return result;
+}
+
+/*-------------------------------------------------------------------------*/
+int SLPAuthDigestDAAdvert(unsigned short spistrlen,
+                          const char* spistr,
+                          unsigned long timestamp,
+                          unsigned long bootstamp,
+                          unsigned short urllen,
+                          const char* url,
+                          unsigned short attrlistlen,
+                          const char* attrlist,
+                          unsigned short scopelistlen,
+                          const char* scopelist,
+                          unsigned short daspistrlen,
+                          const char* daspistr,
+                          unsigned char* digest)
+/*-------------------------------------------------------------------------*/
+{
+    int                 result;
+    int                 tmpbufsize;
+    unsigned char*      tmpbuf;
+    unsigned char*      curpos;
+
+    /* assume success */
+    result = 0;
+
+    /*-------------------------------------------------------*/
+    /* Allocate temporary buffer for contiguous data         */
+    /*-------------------------------------------------------*/
+    /* +18 makes room for:  spistrlen   (2 bytes)            */
+    /*                      bootstamp   (4 bytes)            */
+    /*                      urllen      (2 bytes)            */
+    /*                      scopelistlen(2 bytes)            */
+    /*                      attrlistlen (2 bytes)            */
+    /*                      daspistrlen (2 bytes)            */
+    /*                      timestamp   (4 bytes)            */
+    tmpbufsize = spistrlen + urllen + scopelistlen + attrlistlen + daspistrlen + 18;
+    tmpbuf = xmalloc(tmpbufsize);
+    if(tmpbuf == 0)
+    {
+        return SLP_ERROR_INTERNAL_ERROR;
+    }
+    
+    /*-----------------------------------*/
+    /* Copy data into continguous buffer */
+    /*-----------------------------------*/
+    curpos = tmpbuf;
+
+    ToUINT16(curpos,spistrlen);
+    curpos += 2;
+    memcpy(curpos, spistr, spistrlen);
+    curpos += spistrlen;
+
+    ToUINT32(curpos,bootstamp);
+    curpos += 4;
+
+    ToUINT16(curpos,urllen);
+    curpos += 2;
+    memcpy(curpos, url, urllen);
+    curpos += urllen;      
+
+    ToUINT16(curpos,scopelistlen);
+    curpos += 2;
+    memcpy(curpos, scopelist, scopelistlen);
+    curpos += scopelistlen;
+
+    ToUINT16(curpos,attrlistlen);
+    curpos += 2;
+    memcpy(curpos, attrlist, attrlistlen);
+    curpos += attrlistlen;
+
+    ToUINT16(curpos,daspistrlen);
+    curpos += 2;
+    memcpy(curpos, daspistr, daspistrlen);
+    curpos += daspistrlen;
+
+    ToUINT32(curpos,timestamp);
+
+    /*---------------------*/
+    /* Generate the digest */
+    /*---------------------*/
+    if(SLPCryptoSHA1Digest(tmpbuf,
+                           tmpbufsize,
+                           digest))
+    {
+        result = SLP_ERROR_INTERNAL_ERROR;
+    }
+
+    /*------------------------------*/
+    /* Cleanup the temporary buffer */
+    /*------------------------------*/
+    xfree(tmpbuf);
+
+    return result;
+}
+
+
+/*-------------------------------------------------------------------------*/
+int SLPAuthSignDigest(int spistrlen,
+                      const char* spistr,
+                      SLPCryptoDSAKey* key,
+                      unsigned char* digest,
+                      int* authblocklen,
+                      unsigned char** authblock)
+/*-------------------------------------------------------------------------*/
+{
+    int                 signaturelen;
+    int                 result;
+    unsigned char*      curpos;
+    
+    /*----------------------------------------------*/
+    /* Allocate memory for the authentication block */
+    /*----------------------------------------------*/
+    /* +10 makes room for:                          */
+    /*     - the bsd (2 bytes)                      */
+    /*     - the the authblock length (2 bytes)     */
+    /*     - the spi string length (2 bytes)        */
+    /*     - the timestamp (4 bytes)                */
+    signaturelen = SLPCryptoDSASignLen(key);
+    *authblocklen = spistrlen + signaturelen + 10;
+    *authblock = (unsigned char*)xmalloc(*authblocklen);
+    if(*authblock == 0)
+    {
+        result = SLP_ERROR_INTERNAL_ERROR;
+        goto ERROR;
+    }
+    
+    /*---------------------------------------------------------*/
+    /* Fill in the Authblock with everything but the signature */
+    /*---------------------------------------------------------*/
+    curpos = *authblock;
+    ToUINT16(curpos,0x0002); /* the BSD for DSA-SHA1 */
+    curpos += 2;
+    ToUINT16(curpos,*authblocklen);
+    curpos += 2;
+    ToUINT32(curpos,0xffffffff); /* very long expiration (for now) */
+    curpos += 4;
+    ToUINT16(curpos, spistrlen);
+    curpos += 2;
+    memcpy(curpos, spistr, spistrlen);
+    curpos += spistrlen;
+
+    /*---------------------------------------------*/
+    /* Sign the digest and put it in the authblock */
+    /*---------------------------------------------*/
+    if( SLPCryptoDSASign(key,
+                         digest,
+                         SLPAUTH_SHA1_DIGEST_SIZE,
+                         curpos,
+                         &signaturelen))
+    {
+        result = SLP_ERROR_INTERNAL_ERROR;
+        goto ERROR;
+    }
+
+    /*---------*/
+    /* Success */
+    /*---------*/ 
+    
+    return 0;
+
+
+ERROR:
+    
+    /*-------------------------------*/
+    /* Clean up and return errorcode */
+    /*-------------------------------*/ 
+    if(authblock) xfree(*authblock);
+    *authblock = 0;
+    *authblocklen = 0;
+    
+    return result;
+}
+
+/*-------------------------------------------------------------------------*/
+int SLPVerifyDigest(SLPSpiHandle hspi,
+                    int emptyisfail,
+                    SLPCryptoDSAKey* key,
+                    unsigned char* digest,
+                    int authcount,
+                    const SLPAuthBlock* autharray)
+/*-------------------------------------------------------------------------*/
+{
+    int                 i;
+    int                 signaturelen;
+    int                 result;
+    unsigned long       timestamp;
+    
+    /*-----------------------------------*/
+    /* Should we fail on emtpy authblock */
+    /*-----------------------------------*/
+    if(emptyisfail)
+    {
+        result = SLP_ERROR_AUTHENTICATION_FAILED;
+    }
+    else
+    {
+        result = SLP_ERROR_OK;
+    }  
+    
+    /*-----------------*/
+    /* Get a timestamp */
+    /*-----------------*/
+    timestamp = time(NULL);
+
+    /*------------------------------------------------------*/
+    /* Iterate and check all authentication blocks          */
+    /*------------------------------------------------------*/
+    /* If any one of the authblocks can be verified then we */
+    /* accept it                                            */
+    for(i=0;i<authcount;i++)
+    {
+        /*-------------------------------*/
+        /* Get a public key for the SPI  */
+        /*-------------------------------*/
+        key = SLPSpiGetDSAKey(hspi,
+                              SLPSPI_KEY_TYPE_PUBLIC,
+                              autharray[i].spistrlen,
+                              autharray[i].spistr,
+                              &key);
+        
+        /* Continue if we have a key and if the authenticator is not */
+        /* timed out                                                 */
+        if(key && timestamp <= autharray[i].timestamp)
+        {
+        
+            /*------------------------------------------------------------*/
+            /* Calculate the size of the DSA signature from the authblock */
+            /*------------------------------------------------------------*/
+            /* we have to calculate the signature length since            */
+            /* autharray[i].length is (stupidly) the length of the entire */
+            /* authblock                                                  */
+            signaturelen = autharray[i].length - (autharray[i].spistrlen + 10);
+    
+            /*----------------------*/
+            /* Verify the signature */
+            /*----------------------*/
+            if(SLPCryptoDSAVerify(key,
+                                  digest,
+                                  SLPAUTH_SHA1_DIGEST_SIZE,
+                                  autharray[i].authstruct,
+                                  signaturelen))
+            {
+                break;
+            }
+
+            result = SLP_ERROR_AUTHENTICATION_FAILED;
+        }
+    }
+    
+    return result;
+}
+
+
+
+/*=========================================================================*/
+int SLPAuthVerifyString(SLPSpiHandle hspi,
+                        int emptyisfail,
+                        unsigned short stringlen,
+                        const char* string,
+                        int authcount,
+                        const SLPAuthBlock* autharray)
+/* Verify authenticity of  the specified attribute list                    */
+/*                                                                         */
+/* Parameters: hspi        (IN) open SPI handle                            */
+/*             emptyisfail (IN) if non-zero, messages without authblocks   */
+/*                              will fail                                  */
+/*             stringlen   (IN) the length of string to verify             */
+/*             string      (IN) the list to verify                         */
+/*             authcount   (IN) the number of blocks in autharray          */
+/*             autharray   (IN) array of authblocks                        */
+/*                                                                         */
+/* Returns: 0 on success or SLP_ERROR_xxx code on failure                  */
+/*=========================================================================*/
+{
+    int                 i;
+    int                 signaturelen;
+    int                 result;
+    unsigned long       timestamp;
+    SLPCryptoDSAKey*    key = 0;
+    unsigned char       digest[SLPAUTH_SHA1_DIGEST_SIZE];
+    
+    /*-----------------------------------*/
+    /* Should we fail on emtpy authblock */
+    /*-----------------------------------*/
+    if(emptyisfail)
+    {
+        result = SLP_ERROR_AUTHENTICATION_FAILED;
+    }
+    else
+    {
+        result = SLP_ERROR_OK;
+    }  
+    
+    /*-----------------*/
+    /* Get a timestamp */
+    /*-----------------*/
+    timestamp = time(NULL);
+
+    /*------------------------------------------------------*/
+    /* Iterate and check all authentication blocks          */
+    /*------------------------------------------------------*/
+    /* If any one of the authblocks can be verified then we */
+    /* accept it                                            */
+    for(i=0;i<authcount;i++)
+    {
+        /*-------------------------------*/
+        /* Get a public key for the SPI  */
+        /*-------------------------------*/
+        key = SLPSpiGetDSAKey(hspi,
+                              SLPSPI_KEY_TYPE_PUBLIC,
+                              autharray[i].spistrlen,
+                              autharray[i].spistr,
+                              &key);
+        
+        /* Continue if we have a key and if the authenticator is not */
+        /* timed out                                                 */
+        if(key && timestamp <= autharray[i].timestamp)
+        {
+        
+            /*--------------------------*/
+            /* Generate the SHA1 digest */
+            /*--------------------------*/
+            result = SLPAuthDigestString(autharray[i].spistrlen,
+                                         autharray[i].spistr,
+                                         stringlen,
+                                         string,
+                                         autharray[i].timestamp,
+                                         digest);
+            if(result == 0)
+            {
+                /*------------------------------------------------------------*/
+                /* Calculate the size of the DSA signature from the authblock */
+                /*------------------------------------------------------------*/
+                /* we have to calculate the signature length since            */
+                /* autharray[i].length is (stupidly) the length of the entire */
+                /* authblock                                                  */
+                signaturelen = autharray[i].length - (autharray[i].spistrlen + 10);
+        
+                /*----------------------*/
+                /* Verify the signature */
+                /*----------------------*/
+                if(SLPCryptoDSAVerify(key,
+                                      digest,
+                                      sizeof(digest),
+                                      autharray[i].authstruct,
+                                      signaturelen))
+                {
+                    break;
+                }
+    
+                result = SLP_ERROR_AUTHENTICATION_FAILED;
+            }
+        }
+    }
+    
+    if(key) SLPCryptoDSAKeyDestroy(key);
+   
+    return result;
+}
+
+
+/*=========================================================================*/
+int SLPAuthVerifyUrl(SLPSpiHandle hspi,
+                     int emptyisfail,
+                     const SLPUrlEntry* urlentry)
+/* Verify authenticity of  the specified url entry                         */
+/*                                                                         */
+/* Parameters: hspi         (IN) open SPI handle                            */
+/*             emptyisfail  (IN) if non-zero, messages without authblocks  */
+/*                               will fail                                 */
+/*             urlentry     (IN) the url entry to verify                   */
+/*                                                                         */
+/* Returns: 0 on success or SLP_ERROR_xxx code on failure                  */
+/*=========================================================================*/
+{
+    return SLPAuthVerifyString(hspi,
+                               emptyisfail,
+                               urlentry->urllen,
+                               urlentry->url,
+                               urlentry->authcount,
+                               urlentry->autharray);
+}
+
+
+/*=========================================================================*/
+int SLPAuthVerifyDAAdvert(SLPSpiHandle hspi,
+                          int emptyisfail,
+                          const SLPDAAdvert* daadvert)
+/* Verify authenticity of  the specified DAAdvert                          */
+/*                                                                         */
+/* Parameters: hspi        (IN) open SPI handle                            */
+/*                         (IN) if non-zero, messages without authblocks   */
+/*                              will fail                                  */
+/*             spistrlen   (IN) length of the spi string                   */
+/*             sprstr      (IN) the spi string                             */
+/*             daadvert    (IN) the DAAdvert to verify                     */
+/*                                                                         */
+/* Returns: 0 on success or SLP_ERROR_xxx code on failure                  */
+/*=========================================================================*/
+{
+    int                 i;
+    int                 signaturelen;
+    int                 result;
+    unsigned long       timestamp;
+    const SLPAuthBlock* autharray;
+    int                 authcount;
+    SLPCryptoDSAKey*    key = 0;
+    unsigned char       digest[SLPAUTH_SHA1_DIGEST_SIZE];
+    
+    /*-----------------------------------*/
+    /* Should we fail on emtpy authblock */
+    /*-----------------------------------*/
+    if(emptyisfail)
+    {
+        result = SLP_ERROR_AUTHENTICATION_FAILED;
+    }
+    else
+    {
+        result = SLP_ERROR_OK;
+    }  
+    
+    /*-----------------*/
+    /* Get a timestamp */
+    /*-----------------*/
+    timestamp = time(NULL);
+
+    /*------------------------------------------------------*/
+    /* Iterate and check all authentication blocks          */
+    /*------------------------------------------------------*/
+    /* If any one of the authblocks can be verified then we */
+    /* accept it                                            */
+    authcount = daadvert->authcount;
+    autharray = daadvert->autharray;
+    for(i=0;i<authcount;i++)
+    {
+        /*-------------------------------*/
+        /* Get a public key for the SPI  */
+        /*-------------------------------*/
+        key = SLPSpiGetDSAKey(hspi,
+                              SLPSPI_KEY_TYPE_PUBLIC,
+                              autharray[i].spistrlen,
+                              autharray[i].spistr,
+                              &key);
+        
+        /* Continue if we have a key and if the authenticator is not */
+        /* timed out                                                 */
+        if(key && timestamp <= autharray[i].timestamp)
+        {
+        
+            /*--------------------------*/
+            /* Generate the SHA1 digest */
+            /*--------------------------*/
+            result = SLPAuthDigestDAAdvert(autharray[i].spistrlen,
+                                           autharray[i].spistr,
+                                           autharray[i].timestamp,
+                                           daadvert->bootstamp,
+                                           daadvert->urllen,
+                                           daadvert->url,
+                                           daadvert->attrlistlen,
+                                           daadvert->attrlist,
+                                           daadvert->scopelistlen,
+                                           daadvert->scopelist,
+                                           daadvert->spilistlen,
+                                           daadvert->spilist,
+                                           digest);
+            if(result == 0)
+            {
+                /*------------------------------------------------------------*/
+                /* Calculate the size of the DSA signature from the authblock */
+                /*------------------------------------------------------------*/
+                /* we have to calculate the signature length since            */
+                /* autharray[i].length is (stupidly) the length of the entire */
+                /* authblock                                                  */
+                signaturelen = autharray[i].length - (autharray[i].spistrlen + 10);
+        
+                /*----------------------*/
+                /* Verify the signature */
+                /*----------------------*/
+                if(SLPCryptoDSAVerify(key,
+                                      digest,
+                                      sizeof(digest),
+                                      autharray[i].authstruct,
+                                      signaturelen))
+                {
+                    break;
+                }
+    
+                result = SLP_ERROR_AUTHENTICATION_FAILED;
+            }
+        }
+    }
+    
+    if(key) SLPCryptoDSAKeyDestroy(key);
+   
+    return result;
+}
+
+
+/*=========================================================================*/
+int SLPAuthVerifySAAdvert(SLPSpiHandle hspi,
+                          int emptyisfail,
+                          const SLPSAAdvert* saadvert)
+/* Verify authenticity of  the specified SAAdvert                          */
+/*                                                                         */
+/* Parameters: hspi        (IN) open SPI handle                            */
+/*             emptyisfail (IN) if non-zero, messages without authblocks   */
+/*                              will fail                                  */
+/*             spistrlen   (IN) length of the spi string                   */
+/*             sprstr      (IN) the spi string                             */
+/*             saadvert    (IN) the SAADVERT to verify                     */
+/*                                                                         */
+/* Returns: 0 on success or SLP_ERROR_xxx code on failure                  */
+/*=========================================================================*/
+{
+    return 0;
+}
+
+
+/*=========================================================================*/
+int SLPAuthSignString(SLPSpiHandle hspi,
+                      int spistrlen,
+                      const char* spistr,
+                      unsigned short stringlen,
+                      const char* string,
+                      int* authblocklen,
+                      unsigned char** authblock)
+/* Generate an authblock signature for an attribute list                   */
+/*                                                                         */
+/* Parameters: hspi         (IN) open SPI handle                           */
+/*             spistrlen    (IN) length of the SPI string                  */
+/*             spistr       (IN) SPI to sign with                          */
+/*             attrlistlen  (IN) the length of the URL to sign             */
+/*             attrlist     (IN) the url to sign                           */
+/*             authblocklen (OUT) the length of the authblock signature    */
+/*             authblock    (OUT) buffer containing authblock signature    */
+/*                                must be freed by the caller              */ 
+/*                                                                         */
+/* Returns: 0 on success or SLP_ERROR_xxx code on failure                  */
+/*=========================================================================*/
+{
+    int                 result;
+    SLPCryptoDSAKey*    key;
+    unsigned char       digest[20];
+    int                 defaultspistrlen    = 0;
+    char*               defaultspistr       = 0;
+    
+    /* NULL out the authblock and spistr just to be safe */
+    key = 0;
+    *authblock = 0;
+    *authblocklen = 0;
+    spistr = 0;
+    spistrlen = 0;
+
+    /*--------------------------------*/
+    /* Get a private key for the SPI  */
+    /*--------------------------------*/
+    if(spistr)
+    {
+        key = SLPSpiGetDSAKey(hspi,
+                              SLPSPI_KEY_TYPE_PRIVATE,
+                              spistrlen, 
+                              spistr, 
+                              &key);
+    }
+    else
+    {
+        if(SLPSpiGetDefaultSPI(hspi,
+                               SLPSPI_KEY_TYPE_PRIVATE,
+                               &defaultspistrlen,
+                               &defaultspistr))
+        {
+            spistr = defaultspistr;
+            spistrlen = defaultspistrlen;
+
+            key = SLPSpiGetDSAKey(hspi,
+                                  SLPSPI_KEY_TYPE_PRIVATE,
+                                  spistrlen,
+                                  spistr,
+                                  &key);
+        }
+    }
+
+    if(key == 0)
+    {
+        result = SLP_ERROR_AUTHENTICATION_UNKNOWN;
+        goto ERROR;
+    }
+     
+    /*--------------------------*/
+    /* Generate the SHA1 digest */
+    /*--------------------------*/
+    result = SLPAuthDigestString(spistrlen,
+                                 spistr,
+                                 stringlen,
+                                 string,
+                                 0xffffffff, /* very long expiration (for now) */
+                                 digest);
+    
+    /*---------------------------------------------*/
+    /* Sign the digest and put it in the authblock */
+    /*---------------------------------------------*/
+    if(result == 0)
+    {
+        result = SLPAuthSignDigest(spistrlen,
+                                   spistr,
+                                   key,
+                                   digest,
+                                   authblocklen,
+                                   authblock);
+    }
+
+ERROR:
+    /*---------*/
+    /* Cleanup */
+    /*---------*/ 
+    if(defaultspistr) xfree(defaultspistr);
+    if(key) SLPCryptoDSAKeyDestroy(key);
+    return result;
+}
+
+
+/*=========================================================================*/
+int SLPAuthSignUrl(SLPSpiHandle hspi,
+                   int spistrlen,
+                   const char* spistr,
+                   unsigned short urllen,
+                   const char* url,
+                   int* authblocklen,
+                   unsigned char** authblock)
+/* Generate an authblock signature for a Url                               */
+/*                                                                         */
+/* Parameters: hspi         (IN) open SPI handle                           */
+/*             spistrlen    (IN) length of the SPI string                  */
+/*             spistr       (IN) SPI to sign with                          */
+/*             urllen       (IN) the length of the URL to sign             */
+/*             url          (IN) the url to sign                           */
+/*             authblocklen (OUT) the length of the authblock signature    */
+/*             authblock    (OUT) buffer containing authblock signature    */
+/*                                must be freed by the caller              */
+/*                                                                         */
+/* Returns: 0 on success or SLP_ERROR_xxx code on failure                  */
+/*=========================================================================*/
+{
+    return  SLPAuthSignString(hspi,
+                              spistrlen,
+                              spistr,
+                              urllen,
+                              url,
+                              authblocklen,
+                              authblock);
+}
+
+
+/*=========================================================================*/
+int SLPAuthSignDAAdvert(SLPSpiHandle hspi,
+                        unsigned short spistrlen,
+                        const char* spistr,
+                        unsigned long bootstamp,
+                        unsigned short urllen,
+                        const char* url,
+                        unsigned short attrlistlen,
+                        const char* attrlist,
+                        unsigned short scopelistlen,
+                        const char* scopelist,
+                        unsigned short daspistrlen,
+                        const char* daspistr,
+                        int* authblocklen,
+                        unsigned char** authblock)
+/* Generate an authblock signature for a DAADVERT                          */
+/*                                                                         */
+/* Parameters: hspi         (IN) open SPI handle                           */
+/*             spistrlen (IN) length of the spi string                     */
+/*             sprstr (IN) the spi string                                  */
+/*             bootstamp (IN) the statless DA boot timestamp               */
+/*             urllen (IN) the length of the URL to sign                   */
+/*             url (IN) the url to sign                                    */
+/*             attrlistlen (IN) the length of the URL to sign              */
+/*             attrlist (IN) the url to sign                               */
+/*             scopelistlen (IN) the length of the DA's scope list         */
+/*             scopelist (IN) the DA's scope list                          */
+/*             daspistrlen (IN) the length of the list of DA's SPIs        */
+/*             daspistr (IN) the list of the DA's SPI's                    */
+/*             authblocklen (OUT) the length of the authblock signature    */
+/*             authblock (OUT) buffer containing authblock signature must  */
+/*                             be freed by the caller                      */
+/*                                                                         */
+/* Returns: 0 on success or SLP_ERROR_xxx code on failure                  */
+/*=========================================================================*/
+{
+    int                 result;
+    SLPCryptoDSAKey*    key;
+    unsigned char       digest[20];
+    int                 defaultspistrlen    = 0;
+    char*               defaultspistr       = 0;
+    
+    /* NULL out the authblock and spistr just to be safe */
+    key = 0;
+    *authblock = 0;
+    *authblocklen = 0;
+    spistr = 0;
+    spistrlen = 0;
+
+    /*--------------------------------*/
+    /* Get a private key for the SPI  */
+    /*--------------------------------*/
+    if(spistr)
+    {
+        key = SLPSpiGetDSAKey(hspi,
+                              SLPSPI_KEY_TYPE_PRIVATE,
+                              spistrlen, 
+                              spistr, 
+                              &key);
+    }
+    else
+    {
+        if(SLPSpiGetDefaultSPI(hspi,
+                               SLPSPI_KEY_TYPE_PRIVATE,
+                               &defaultspistrlen,
+                               &defaultspistr))
+        {
+            spistr = defaultspistr;
+            spistrlen = defaultspistrlen;
+
+            key = SLPSpiGetDSAKey(hspi,
+                                  SLPSPI_KEY_TYPE_PRIVATE,
+                                  spistrlen,
+                                  spistr,
+                                  &key);
+        }
+    }
+
+    if(key == 0)
+    {
+        result = SLP_ERROR_AUTHENTICATION_UNKNOWN;
+        goto ERROR;
+    }
+     
+    /*--------------------------*/
+    /* Generate the SHA1 digest */
+    /*--------------------------*/
+    result = SLPAuthDigestDAAdvert(spistrlen,
+                                   spistr,
+                                   0xffffffff,
+                                   bootstamp,
+                                   urllen,
+                                   url,
+                                   attrlistlen,
+                                   attrlist,
+                                   scopelistlen,
+                                   scopelist,
+                                   daspistrlen,
+                                   daspistr,
+                                   digest);
+
+    /*---------------------------------------------*/
+    /* Sign the digest and put it in the authblock */
+    /*---------------------------------------------*/
+    if(result == 0)
+    {
+        result = SLPAuthSignDigest(spistrlen,
+                                   spistr,
+                                   key,
+                                   digest,
+                                   authblocklen,
+                                   authblock);
+    }
+
+ERROR:
+    /*---------*/
+    /* Cleanup */
+    /*---------*/ 
+    if(defaultspistr) xfree(defaultspistr);
+    if(key) SLPCryptoDSAKeyDestroy(key);
+    return result;
+}
+
+
+/*=========================================================================*/
+int SLPAuthSignSAAdvert(unsigned short spistrlen,
+                        const char* spistr,
+                        unsigned short urllen,
+                        const char* url,
+                        unsigned short attrlistlen,
+                        const char* attrlist,
+                        unsigned short scopelistlen,
+                        const char* scopelist,
+                        int* authblocklen,
+                        unsigned char** authblock)
+/* Generate an authblock signature for a SAADVERT                          */
+/*                                                                         */
+/* Parameters: spistrlen (IN) length of the spi string                     */
+/*             sprstr (IN) the spi string                                  */
+/*             urllen (IN) the length of the URL to sign                   */
+/*             url (IN) the url to sign                                    */
+/*             attrlistlen (IN) the length of the URL to sign              */
+/*             attrlist (IN) the url to sign                               */
+/*             scopelistlen (IN) the length of the DA's scope list         */
+/*             scopelist (IN) the DA's scope list                          */
+/*             authblocklen (OUT) the length of the authblock signature    */
+/*             authblock (OUT) buffer containing authblock signature       */
+/*                                                                         */
+/* Returns: 0 on success or SLP_ERROR_xxx code on failure                  */
+/*=========================================================================*/
+{
+    *authblocklen = 0;
+    *authblock = 0;
+    return 0;
+}
+
--- common/slp_crypto.c
+++ common/slp_crypto.c	2003/12/15 17:15:46
@@ -0,0 +1,183 @@
+/***************************************************************************/
+/*                                                                         */
+/* Project:     OpenSLP - OpenSource implementation of Service Location    */
+/*              Protocol                                                   */
+/*                                                                         */
+/* File:        slp_crpyto.c                                               */
+/*                                                                         */
+/* Abstract:    Primitive cryptographic functions to support DSA signature */
+/*              of SHA1 digests.  Current implementation is uses the       */
+/*              OpenSSL (http://www.openssl.org)) crypto library.          */
+/*                                                                         */
+/*-------------------------------------------------------------------------*/
+/*                                                                         */
+/*     Please submit patches to http://www.openslp.org                     */
+/*                                                                         */
+/*-------------------------------------------------------------------------*/
+/*                                                                         */
+/* Copyright (C) 2000 Caldera Systems, Inc                                 */
+/* All rights reserved.                                                    */
+/*                                                                         */
+/* Redistribution and use in source and binary forms, with or without      */
+/* modification, are permitted provided that the following conditions are  */
+/* met:                                                                    */ 
+/*                                                                         */
+/*      Redistributions of source code must retain the above copyright     */
+/*      notice, this list of conditions and the following disclaimer.      */
+/*                                                                         */
+/*      Redistributions in binary form must reproduce the above copyright  */
+/*      notice, this list of conditions and the following disclaimer in    */
+/*      the documentation and/or other materials provided with the         */
+/*      distribution.                                                      */
+/*                                                                         */
+/*      Neither the name of Caldera Systems nor the names of its           */
+/*      contributors may be used to endorse or promote products derived    */
+/*      from this software without specific prior written permission.      */
+/*                                                                         */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     */
+/* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT      */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR   */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA      */
+/* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON       */
+/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    */
+/*                                                                         */
+/***************************************************************************/
+
+#include "slp_crypto.h"
+#include "slp_message.h"
+  
+/*=========================================================================*/
+int SLPCryptoSHA1Digest(const unsigned char* data,
+                        int datalen,
+                        unsigned char* digest)
+/* Generate a SHA1 digest for the specified block data                     */
+/*                                                                         */
+/* Parameters: data     (IN)  pointer to buffer that to be hashed          */
+/*             datalen  (IN)  size of the data buffer in bytes             */
+/*             digest   (OUT) pointer to buffer of at least 20 bytes in    */
+/*                            size where the digest will be copied         */
+/*                                                                         */
+/* Returns: zero on success.  non-zero on failure                          */
+/*=========================================================================*/
+{
+    if(SHA1(data,datalen,digest))
+    {
+        return 0;
+    }
+
+    return -1;
+}
+
+
+/*=========================================================================*/
+SLPCryptoDSAKey* SLPCryptoDSAKeyDup(SLPCryptoDSAKey* dsa)
+/* Duplicates the specified key                                            */
+/*                                                                         */
+/* Parameters: dsa (IN) the key to duplicate                               */
+/*                                                                         */
+/* Returns: Pointer to the duplicated key.  NULL on failure. Caller is     */
+/*          responsible for SLPCryptoDSAKeyDestroy()ing the returned       */
+/*          pointer                                                        */
+/*=========================================================================*/
+{
+    SLPCryptoDSAKey* result;
+    
+    result =  DSA_new();
+    if(result)
+    {
+        result->p = BN_dup(dsa->p);
+        result->q = BN_dup(dsa->q);
+        result->g = BN_dup(dsa->g);
+        result->priv_key = BN_dup(dsa->priv_key);
+        result->pub_key = BN_dup(dsa->pub_key);
+    }
+
+    return result;
+}
+
+/*=========================================================================*/
+void SLPCryptoDSAKeyDestroy(SLPCryptoDSAKey* dsa)
+/* Destroy a key that was created by SLPCryptoDSAKeyCreate(). Care should  */
+/* be taken to make sure all private keys are destroyed                    */
+/*                                                                         */
+/* Parameters: dsa (IN) the key to destroy                                 */
+/*                                                                         */
+/* Returns:  None                                                          */
+/*=========================================================================*/
+{
+    DSA_free(dsa);
+}
+
+
+/*=========================================================================*/
+int SLPCryptoDSASignLen(SLPCryptoDSAKey* key)
+/* Determine the length of a signatures produced with specified key.       */
+/*                                                                         */
+/* Parameters: key (IN) the key that will be used for signing              */
+/*                                                                         */
+/* Returns: The length of signatures in bytes                              */
+/*=========================================================================*/
+{
+    return DSA_size(key);
+}
+
+
+/*=========================================================================*/
+int SLPCryptoDSASign(SLPCryptoDSAKey* key,
+                     const unsigned char* digest,
+                     int digestlen,
+                     unsigned char* signature,
+                     int* signaturelen)
+/* Sign the specified digest with the specified DSA key                    */
+/*                                                                         */
+/* Parameters: key          (IN)  Signing (private) key                    */
+/*             digest       (IN)  pointer to digest buffer                 */
+/*             digestlen    (IN)  length of the digest buffer              */
+/*             signature    (OUT) buffer that will hold the ASN.1 DER      */
+/*                                encoded signature.                       */
+/*             signaturelen (OUT) The length of the signature buffer       */
+/*                                SLPCryptoDSASignLen(key) should be       */
+/*                                called to determine how big signature    */
+/*                                should be.                               */
+/*                                                                         */
+/* Returns: zero on success. non-zero on failure                           */
+/*=========================================================================*/
+{
+    return DSA_sign(0, /* it does not look like the type param is used? */
+                    digest,
+                    digestlen,
+                    signature,
+                    signaturelen,
+                    key) == 0;
+}
+
+
+/*=========================================================================*/
+int SLPCryptoDSAVerify(SLPCryptoDSAKey* key,
+                       const unsigned char* digest,
+                       int digestlen,
+                       const unsigned char* signature,
+                       int signaturelen)
+/* Verify a DSA signature to ensure it matches the specified digest        */
+/*                                                                         */
+/* Parameters: key          (IN) Verifying (public) key                    */
+/*                          (IN) pointer to the digest buffer              */
+/*                          (IN) length of the digest buffer               */
+/*                          (IN) the ASN.1 DER encoded signature           */
+/*                          (IN) the length of the signature               */
+/*                                                                         */
+/* Returns: 1 if the signature is valid, 0 of it is not                    */
+/*=========================================================================*/
+{
+    return DSA_verify(0, /* it does not look like the type param is used? */
+                      digest,
+                      digestlen,
+                      (unsigned char*)signature,  /* broken DSA_verify() declaration */
+                      signaturelen,
+                      key);
+}
--- common/slp_spi.c
+++ common/slp_spi.c	2003/12/15 17:15:46
@@ -0,0 +1,459 @@
+/***************************************************************************/
+/*                                                                         */
+/* Project:     OpenSLP - OpenSource implementation of Service Location    */
+/*              Protocol Version 2                                         */
+/*                                                                         */
+/* File:        slp_spi.h                                                  */
+/*                                                                         */
+/* Abstract:    Functions for fetching SPI information from the filesystem */
+/*              Current implementation uses OpenSSL. For details see       */
+/*              (see http://www.openssl.org                                */
+/*                                                                         */
+/*-------------------------------------------------------------------------*/
+/*                                                                         */
+/*     Please submit patches to http://www.openslp.org                     */
+/*                                                                         */
+/*-------------------------------------------------------------------------*/
+/*                                                                         */
+/* Copyright (C) 2000 Caldera Systems, Inc                                 */
+/* All rights reserved.                                                    */
+/*                                                                         */
+/* Redistribution and use in source and binary forms, with or without      */
+/* modification, are permitted provided that the following conditions are  */
+/* met:                                                                    */ 
+/*                                                                         */
+/*      Redistributions of source code must retain the above copyright     */
+/*      notice, this list of conditions and the following disclaimer.      */
+/*                                                                         */
+/*      Redistributions in binary form must reproduce the above copyright  */
+/*      notice, this list of conditions and the following disclaimer in    */
+/*      the documentation and/or other materials provided with the         */
+/*      distribution.                                                      */
+/*                                                                         */
+/*      Neither the name of Caldera Systems nor the names of its           */
+/*      contributors may be used to endorse or promote products derived    */
+/*      from this software without specific prior written permission.      */
+/*                                                                         */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     */
+/* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT      */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR   */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA      */
+/* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON       */
+/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    */
+/*                                                                         */
+/***************************************************************************/
+
+#include "slp_spi.h"
+#include "slp_xmalloc.h"
+
+#include <string.h>
+#include <stdio.h>
+#include <openssl/pem.h>
+#include <openssl/bn.h>
+
+
+#define MAX_SPI_ENTRY_LEN   1024
+#define PUBLIC_TOKEN        "PUBLIC"
+#define PRIVATE_TOKEN       "PRIVATE"
+
+
+/*-------------------------------------------------------------------------*/
+void SLPSpiEntryFree(SLPSpiEntry* victim)
+/*-------------------------------------------------------------------------*/
+{
+    if(victim->keyfilename) xfree(victim->keyfilename);
+    if(victim->spistr) xfree(victim->spistr);
+    if(victim->key) SLPCryptoDSAKeyDestroy(victim->key);
+    if(victim) xfree(victim);
+}
+
+/*-------------------------------------------------------------------------*/
+SLPSpiEntry* SLPSpiEntryFind(SLPList* cache,
+                             int keytype,
+                             int spistrlen,
+                             const char* spistr)
+/* pass in null spistr to find the first Cached entry                      */
+/*-------------------------------------------------------------------------*/
+{
+    SLPSpiEntry* entry = (SLPSpiEntry*)cache->head;
+    while(entry)
+    {
+        if(spistr)
+        {
+            if (entry->spistrlen == spistrlen &&
+                memcmp(entry->spistr,spistr,spistrlen) == 0 &&
+                        entry->keytype == keytype)
+            {
+                return entry;
+            }
+        }
+        else
+        {
+            if(keytype == SLPSPI_KEY_TYPE_ANY || entry->keytype == keytype)
+            {
+                return entry;
+            }
+        }
+        entry = (SLPSpiEntry*)entry->listitem.next;
+    }
+
+    return 0;
+}
+
+/*-------------------------------------------------------------------------*/
+SLPCryptoDSAKey* SLPSpiReadKeyFile(const char* keyfile, int keytype)
+/*-------------------------------------------------------------------------*/
+{
+    FILE*            fp;
+    SLPCryptoDSAKey* result = 0;
+
+    fp = fopen(keyfile,"r");
+    if(fp)
+    {
+        if(keytype == SLPSPI_KEY_TYPE_PUBLIC)
+        {
+            result = PEM_read_DSA_PUBKEY(fp, &result, NULL, NULL);
+        }
+        else if (keytype == SLPSPI_KEY_TYPE_PRIVATE)
+        {
+            result =  PEM_read_DSAPrivateKey(fp, &result, NULL, NULL);
+        }
+
+	    fclose(fp);
+    }
+
+    return result;
+}
+
+
+/*-------------------------------------------------------------------------*/
+SLPSpiEntry* SLPSpiReadSpiFile(FILE* fp, int keytype)
+/* Caller needs to free returned memory SLPSpiEntryFree()                  */
+/*-------------------------------------------------------------------------*/
+{
+    SLPSpiEntry*    result;
+    char            tmp;
+    char*           line;
+    char*           slider1;
+    char*           slider2;
+
+    /*----------------------------*/
+    /* Allocate memory for result */
+    /*----------------------------*/
+    line = (char*) xmalloc(MAX_SPI_ENTRY_LEN);
+    result = (SLPSpiEntry*) xmalloc(sizeof(SLPSpiEntry));
+    if(result == 0 || line == 0)
+    {
+        return 0;
+    }
+    memset(result,0,sizeof(SLPSpiEntry));
+    
+
+    /*---------------------------*/
+    /* Read the next valid entry */
+    /*---------------------------*/
+    while(fgets(line, MAX_SPI_ENTRY_LEN, fp))
+    {
+        /*----------------------*/
+        /* read the first token */
+        /*----------------------*/
+        slider1 = line;
+        /* skip leading whitespace */
+        while(*slider1 && *slider1 <= 0x20) slider1++;
+        /* skip all white lines */
+        if(*slider1 == 0) continue;
+        /* skip commented lines */
+        if(*slider1 == '#') continue;
+        /* PUBLIC|PRIVATE */
+        slider2 = slider1;
+        while(*slider2 && *slider2 > 0x20) slider2++;
+        if(strncasecmp(PUBLIC_TOKEN,slider1,slider2-slider1) == 0)
+        {
+            if(keytype == SLPSPI_KEY_TYPE_PRIVATE) continue;
+            result->keytype = SLPSPI_KEY_TYPE_PUBLIC;
+        }
+        else if(strncasecmp(PRIVATE_TOKEN,slider1,slider2-slider1) == 0)
+        {
+            if(keytype == SLPSPI_KEY_TYPE_PUBLIC) continue;
+            result->keytype = SLPSPI_KEY_TYPE_PRIVATE;
+        }
+        else
+        {
+            /* unknown token */
+            continue;
+        }
+
+        /*-----------------------*/
+        /* read the second token */
+        /*-----------------------*/
+        slider1=slider2;
+        /* skip leading whitespace */
+        while(*slider1 && *slider1 <= 0x20) slider1++;
+        /* SPI string */
+        slider2 = slider1;
+        while(*slider2 && *slider2 > 0x20) slider2++;
+        /* SPI string is at slider1 length slider2 - slider1 */
+    
+        result->spistr = (char*)xmalloc(slider2-slider1);
+        if(result->spistr)
+        {
+            memcpy(result->spistr,slider1,slider2-slider1);
+            result->spistrlen = slider2-slider1;    
+        }   
+                
+        /*----------------------*/
+        /* read the third token */
+        /*----------------------*/
+        slider1=slider2;
+        /* skip leading whitespace */
+        while(*slider1 && *slider1 <= 0x20) slider1++;
+        /* SPI string */
+        slider2 = slider1;
+        while(*slider2 && *slider2 > 0x20) slider2++;
+        /* key file path is at slider1 length slider2 - slider1 */
+        tmp = *slider2; 
+        *slider2 = 0;
+        result->keyfilename = xstrdup(slider1);
+        result->key = 0; /* read it later */ 
+        *slider2 = tmp;
+        
+        /*-----------------*/
+        /* See what we got */
+        /*-----------------*/
+        if(result &&
+           result->spistr &&
+           result->keyfilename)
+        {
+            goto SUCCESS;
+        }
+
+        if(result->keyfilename) xfree(result->keyfilename);
+        if(result->spistr) xfree(result->spistr);
+    }
+
+    if (result)
+    { 
+        xfree(result);
+        result = 0;
+    }
+    
+SUCCESS:
+
+    if (line) xfree(line);
+
+    return result;
+}
+
+
+/*=========================================================================*/
+SLPSpiHandle SLPSpiOpen(const char* spifile, int cacheprivate)
+/* Initializes SLP SPI data storage.                                       */
+/*                                                                         */
+/* Parameters: spifile      (IN) path of slp.spi file                      */
+/*             cacheprivate (IN) should private keys be cached in handle   */
+/*                                                                         */
+/* Returns:  valid pointer.  NULL on failure                               */
+/*=========================================================================*/
+{
+    FILE*           fp;
+    SLPSpiHandle    result = 0;
+    SLPSpiEntry*    spientry;      
+
+    fp = fopen(spifile,"r");
+    if(fp)
+    {
+        result = xmalloc(sizeof(struct _SLPSpiHandle));
+        if(result == 0) return 0;
+        memset(result, 0, sizeof(struct _SLPSpiHandle));
+        
+        result->spifile = xstrdup(spifile);
+        result->cacheprivate = cacheprivate;
+        while(1)
+        {
+            spientry = SLPSpiReadSpiFile(fp, SLPSPI_KEY_TYPE_ANY);
+            if(spientry == 0) break;
+            if(spientry->keytype == SLPSPI_KEY_TYPE_PRIVATE &&
+               cacheprivate == 0)
+            {
+                /* destroy the key cause we're not suppose to cache it */
+                SLPCryptoDSAKeyDestroy(spientry->key);
+            }
+            
+            SLPListLinkHead(&(result->cache),(SLPListItem*)spientry);
+        } 
+
+        fclose(fp); 
+    }
+
+    return result;
+}
+
+/*=========================================================================*/
+void SLPSpiClose(SLPSpiHandle hspi)
+/* Release SLP SPI data storage associated with the specified SLPSpiHandle */
+/*                                                                         */
+/* Parameters: hspi (IN) SLPSpiHandle to deinitialize                      */
+/*=========================================================================*/
+{
+    if(hspi)
+    {
+        if(hspi->spifile) xfree(hspi->spifile);
+        while(hspi->cache.count)
+        {
+            SLPSpiEntryFree((SLPSpiEntry*)SLPListUnlink(&(hspi->cache),hspi->cache.head));
+        }
+        
+        xfree(hspi);
+    }
+}
+
+
+/*=========================================================================*/
+char* SLPSpiGetDefaultSPI(SLPSpiHandle hspi, 
+                          int keytype,
+                          int* spistrlen,
+                          char** spistr)
+/* Gets a reference to the default SPI string for the specified keytype    */
+/*                                                                         */
+/* Parameters: hspi      (IN) handle obtained from call to SLPSpiOpen()    */
+/*             keytype   (IN) type of key                                  */
+/*             spistrlen (OUT) length or the returned spistr               */
+/*             spistr    (OUT) pointer to spistr.  MUST be freed by        */
+/*                             caller!!                                    */
+/*                                                                         */
+/* Returns: Pointer to the default SPI string.  Pointer may *not* be NULL  */
+/*          terminated                                                     */
+/*=========================================================================*/
+{
+    SLPSpiEntry* entry;
+    
+    *spistr = 0;
+    *spistrlen = 0;
+
+    if(hspi)
+    {
+            
+        entry = SLPSpiEntryFind(&(hspi->cache),keytype,0,0);
+        if(entry)
+        {
+            *spistr = xmalloc(entry->spistrlen);
+            if(*spistr)
+            {
+                memcpy(*spistr, entry->spistr, entry->spistrlen);
+                *spistrlen = entry->spistrlen;
+            }
+        }
+    }
+
+    return *spistr;
+}
+    
+
+/*=========================================================================*/
+SLPCryptoDSAKey* SLPSpiGetDSAKey(SLPSpiHandle hspi,
+                                 int keytype,
+                                 int spistrlen,
+                                 const char* spistr,
+                                 SLPCryptoDSAKey **key)
+/* Fetches a copy of the private key file used to sign SLP messages.       */
+/*                                                                         */
+/* Parameters: hspi      (IN)  handle obtained from call to SLPSpiOpen()   */
+/*             keytype   (IN)  the type of key desired                     */
+/*             spistrlen (IN)  the length of the spistr                    */
+/*             spistr    (IN)  spistr associated with the key              */
+/*             key       (OUT) the private key.  Caller should use         */
+/*                             SLPCryptoDSAKeyDestroy() to free key memory */
+/*                                                                         */
+/* Returns: A valid pointer. NULL on failure. Caller should use            */
+/*          SLPCryptoDSAKeyDestroy() to free key memory                    */ 
+/*=========================================================================*/
+{
+    SLPSpiEntry*    tmp = 0;
+        
+    /* For safety NULL out the key from the beginning */
+    *key = 0;
+
+    if(hspi)
+    {
+        tmp = SLPSpiEntryFind(&(hspi->cache),
+                              keytype,
+                              spistrlen,
+                              spistr);
+        if(tmp)
+        {
+            if(tmp->key == 0)
+            {
+                if(keytype == SLPSPI_KEY_TYPE_PRIVATE && hspi->cacheprivate == 0)
+                {
+                    *key = SLPSpiReadKeyFile(tmp->keyfilename,SLPSPI_KEY_TYPE_PRIVATE);
+                    return *key;
+                }
+                
+                tmp->key = SLPSpiReadKeyFile(tmp->keyfilename,keytype);
+            }
+
+            *key = SLPCryptoDSAKeyDup(tmp->key);
+        }
+    }
+
+    return *key;
+}
+
+
+/*=========================================================================*/
+int SLPSpiCanVerify(SLPSpiHandle hspi,
+                    int spistrlen,
+                    const char* spistr)
+/* Determine if we understand the specified SPI.  No SPI is always         */
+/* returns true                                                            */
+/*                                                                         */
+/* Parameters: hspi      (IN)  handle obtained from call to SLPSpiOpen()   */
+/*             spistrlen (IN)  the length of the spistr                    */
+/*             spistr    (IN)  the SPI string                              */
+/*                                                                         */
+/* Returns     Non-zero if we verify specified the SPI                     */
+/*=========================================================================*/
+{
+    if (hspi == 0)
+    {
+        return 0;
+    }
+
+    if(spistrlen == 0 || spistr == NULL)
+    {
+        return 1;
+    }
+
+    return (SLPSpiEntryFind(&(hspi->cache), 
+                            SLPSPI_KEY_TYPE_PUBLIC,
+                            spistrlen, 
+                            spistr) != 0);
+}
+
+
+/*=========================================================================*/
+int SLPSpiCanSign(SLPSpiHandle hspi,
+                  int spistrlen,
+                  const char* spistr)
+/* Determine if we understand the specified SPI.  No SPI is always         */
+/* return true                                                             */
+/*                                                                         */
+/* Parameters: hspi      (IN)  handle obtained from call to SLPSpiOpen()   */
+/*             spistrlen (IN)  the length of the spistr                    */
+/*             spistr    (IN)  the SPI string                              */
+/*                                                                         */
+/* Returns     Non-zero if we sign using the specified SPI                 */
+/*=========================================================================*/
+{
+    return (SLPSpiEntryFind(&(hspi->cache), 
+                            SLPSPI_KEY_TYPE_PRIVATE,
+                            spistrlen, 
+                            spistr) != 0);
+}
+
+
--- slpd/slpd_spi.c
+++ slpd/slpd_spi.c	2003/12/15 17:15:46
@@ -0,0 +1,83 @@
+/***************************************************************************/
+/*                                                                         */
+/* Project:     OpenSLP - OpenSource implementation of Service Location    */
+/*              Protocol Version 2                                         */
+/*                                                                         */
+/* File:        slpd_spi.c                                                 */
+/*                                                                         */
+/* Abstract:    Functions and variables for slpd usage of common SPI code  */
+/*                                                                         */
+/*-------------------------------------------------------------------------*/
+/*                                                                         */
+/*     Please submit patches to http://www.openslp.org                     */
+/*                                                                         */
+/*-------------------------------------------------------------------------*/
+/*                                                                         */
+/* Copyright (C) 2000 Caldera Systems, Inc                                 */
+/* All rights reserved.                                                    */
+/*                                                                         */
+/* Redistribution and use in source and binary forms, with or without      */
+/* modification, are permitted provided that the following conditions are  */
+/* met:                                                                    */ 
+/*                                                                         */
+/*      Redistributions of source code must retain the above copyright     */
+/*      notice, this list of conditions and the following disclaimer.      */
+/*                                                                         */
+/*      Redistributions in binary form must reproduce the above copyright  */
+/*      notice, this list of conditions and the following disclaimer in    */
+/*      the documentation and/or other materials provided with the         */
+/*      distribution.                                                      */
+/*                                                                         */
+/*      Neither the name of Caldera Systems nor the names of its           */
+/*      contributors may be used to endorse or promote products derived    */
+/*      from this software without specific prior written permission.      */
+/*                                                                         */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     */
+/* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT      */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR   */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA      */
+/* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON       */
+/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    */
+/*                                                                         */
+/***************************************************************************/
+
+
+/*=========================================================================*/
+/* slpd includes                                                           */
+/*=========================================================================*/
+#include "slpd_spi.h"
+
+/*=========================================================================*/
+SLPSpiHandle G_SlpdSpiHandle = 0;
+/*=========================================================================*/
+
+
+/*=========================================================================*/
+int SLPDSpiInit(const char* spifile)
+/*=========================================================================*/
+{
+    if(G_SlpdSpiHandle)
+    {
+        SLPSpiClose(G_SlpdSpiHandle);
+        G_SlpdSpiHandle = 0;
+    }
+   
+    G_SlpdSpiHandle = SLPSpiOpen(spifile,1);
+    return (G_SlpdSpiHandle == 0);
+}
+
+#ifdef DEBUG
+/*=========================================================================*/
+void SLPDSpiDeinit()
+/*=========================================================================*/
+{
+    SLPSpiClose(G_SlpdSpiHandle);
+}
+#endif
+
+
--- slpd/slpd_spi.h
+++ slpd/slpd_spi.h	2003/12/15 17:15:46
@@ -0,0 +1,75 @@
+/***************************************************************************/
+/*                                                                         */
+/* Project:     OpenSLP - OpenSource implementation of Service Location    */
+/*              Protocol Version 2                                         */
+/*                                                                         */
+/* File:        slpd_spi.h                                                 */
+/*                                                                         */
+/* Abstract:    Functions and variables for slpd usage of common SPI code  */
+/*                                                                         */
+/*-------------------------------------------------------------------------*/
+/*                                                                         */
+/*     Please submit patches to http://www.openslp.org                     */
+/*                                                                         */
+/*-------------------------------------------------------------------------*/
+/*                                                                         */
+/* Copyright (C) 2000 Caldera Systems, Inc                                 */
+/* All rights reserved.                                                    */
+/*                                                                         */
+/* Redistribution and use in source and binary forms, with or without      */
+/* modification, are permitted provided that the following conditions are  */
+/* met:                                                                    */ 
+/*                                                                         */
+/*      Redistributions of source code must retain the above copyright     */
+/*      notice, this list of conditions and the following disclaimer.      */
+/*                                                                         */
+/*      Redistributions in binary form must reproduce the above copyright  */
+/*      notice, this list of conditions and the following disclaimer in    */
+/*      the documentation and/or other materials provided with the         */
+/*      distribution.                                                      */
+/*                                                                         */
+/*      Neither the name of Caldera Systems nor the names of its           */
+/*      contributors may be used to endorse or promote products derived    */
+/*      from this software without specific prior written permission.      */
+/*                                                                         */
+/* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS     */
+/* `AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT      */
+/* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR   */
+/* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE CALDERA      */
+/* SYSTEMS OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, */
+/* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT        */
+/* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;  LOSS OF USE,  */
+/* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON       */
+/* ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT */
+/* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE   */
+/* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.    */
+/*                                                                         */
+/***************************************************************************/
+
+#ifndef SLPD_SPI_H_INCLUDED
+
+/*=========================================================================*/
+/* slpd includes                                                           */
+/*=========================================================================*/
+#include "slpd.h"
+
+/*=========================================================================*/
+/* Common code code includes                                               */
+/*=========================================================================*/
+#include "slp_spi.h"  
+
+/*=========================================================================*/
+extern SLPSpiHandle G_SlpdSpiHandle;
+/*=========================================================================*/
+
+
+/*=========================================================================*/
+int SLPDSpiInit(const char* spifile);
+/*=========================================================================*/
+
+
+/*=========================================================================*/
+void SLPDSpiDeinit();
+/*=========================================================================*/
+
+#endif
 
design & coding: Vladimir Lettiev aka crux © 2004-2005, Andrew Avramenko aka liks © 2007-2008
current maintainer: Michael Shigorin