ALT Linux repos
Group :: Networking/Other
RPM: openslp
Main Changelog Spec Patches Sources Download Gear Bugs and FR Repocop
Patch: 03_auth.patch
Download
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