📄 pgplicensenumbernet.c
字号:
/*____________________________________________________________________________
Copyright (C) 2002 PGP Corporation
All rights reserved.
$Id: pgpLicenseNumberNet.c,v 1.16 2002/11/12 21:40:16 ajivsov Exp $
____________________________________________________________________________*/
#include "pgpLicenseNumber.h"
#include "pgpLicenseNumberNet.h"
#include "pgpUtilities.h"
#include "pgpMem.h"
#include "pgpHash.h"
#include "pgpSymmetricCipher.h"
#include "pgpCBC.h"
#include "pgpKeys.h"
#include "pgpEncode.h"
#include "string.h"
#include "pgpErrors.h"
#include "pgpSockets.h"
#include "pgpBigNum.h"
#include "pgpPublicKey.h"
#include "pgpRandomPool.h"
#include "pgpUnicode.h"
#define kPGPLANet_UrlMax 256
#define kPGPLANet_SendSize 2048
#define kPGPLANet_ReceiveSize 2048
static const char tok_ln[]="ln";
static const char tok_companyName[]="companyName";
static const char tok_customerName[]="customerName";
static const char tok_ticket[]="ticket";
static const char tok_scookie[]="scookie";
static const char tok_ticket_stub[]="ticket_stub";
static const char tok_la[]="la";
static const char tok_nameHash[]="nameHash";
/* controls all debug dump on the stderr */
#define PGP_DEBUG_PRINT PGP_DEBUG
/* implementation of DH DL in the generric API that will work for
other DH types. The idea is to have alternative to dhInitDL, say dhInitEC,
while keeping other dh* functions inchanged */
typedef struct DHExchange {
PGPContextRef ctx;
PGPMemoryMgrRef mem;
PGPBoolean is_initiator;
PGPSize sizeInTransit;
PGPBigNumRef x;
PGPBigNumRef t;
PGPBigNumRef gy;
PGPBigNumRef g;
PGPBigNumRef p;
PGPByte *buf;
PGPSize bufSize;
} DHExchange;
typedef DHExchange * pgpDHExchangeRef;
typedef PGPByte byte;
/* IKE group 2 */
/* The prime is 2^1024 - 2^960 - 1 + 2^64 * { [2^894 pi] + 129093 } */
static const PGPByte mod1024bytesG0[] = {
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,
(byte)0xC9,(byte)0x0F,(byte)0xDA,(byte)0xA2,(byte)0x21,(byte)0x68,(byte)0xC2,(byte)0x34,
(byte)0xC4,(byte)0xC6,(byte)0x62,(byte)0x8B,(byte)0x80,(byte)0xDC,(byte)0x1C,(byte)0xD1,
(byte)0x29,(byte)0x02,(byte)0x4E,(byte)0x08,(byte)0x8A,(byte)0x67,(byte)0xCC,(byte)0x74,
(byte)0x02,(byte)0x0B,(byte)0xBE,(byte)0xA6,(byte)0x3B,(byte)0x13,(byte)0x9B,(byte)0x22,
(byte)0x51,(byte)0x4A,(byte)0x08,(byte)0x79,(byte)0x8E,(byte)0x34,(byte)0x04,(byte)0xDD,
(byte)0xEF,(byte)0x95,(byte)0x19,(byte)0xB3,(byte)0xCD,(byte)0x3A,(byte)0x43,(byte)0x1B,
(byte)0x30,(byte)0x2B,(byte)0x0A,(byte)0x6D,(byte)0xF2,(byte)0x5F,(byte)0x14,(byte)0x37,
(byte)0x4F,(byte)0xE1,(byte)0x35,(byte)0x6D,(byte)0x6D,(byte)0x51,(byte)0xC2,(byte)0x45,
(byte)0xE4,(byte)0x85,(byte)0xB5,(byte)0x76,(byte)0x62,(byte)0x5E,(byte)0x7E,(byte)0xC6,
(byte)0xF4,(byte)0x4C,(byte)0x42,(byte)0xE9,(byte)0xA6,(byte)0x37,(byte)0xED,(byte)0x6B,
(byte)0x0B,(byte)0xFF,(byte)0x5C,(byte)0xB6,(byte)0xF4,(byte)0x06,(byte)0xB7,(byte)0xED,
(byte)0xEE,(byte)0x38,(byte)0x6B,(byte)0xFB,(byte)0x5A,(byte)0x89,(byte)0x9F,(byte)0xA5,
(byte)0xAE,(byte)0x9F,(byte)0x24,(byte)0x11,(byte)0x7C,(byte)0x4B,(byte)0x1F,(byte)0xE6,
(byte)0x49,(byte)0x28,(byte)0x66,(byte)0x51,(byte)0xEC,(byte)0xE6,(byte)0x53,(byte)0x81,
(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF,(byte)0xFF
};
static void dhFree( pgpDHExchangeRef exchange ) {
if( !exchange )
return;
if( exchange->g )
PGPFreeBigNum( exchange->g );
if( exchange->x )
PGPFreeBigNum( exchange->x );
if( exchange->t )
PGPFreeBigNum( exchange->t );
if( exchange->gy )
PGPFreeBigNum( exchange->gy );
if( exchange->p )
PGPFreeBigNum( exchange->p );
if( exchange->buf )
PGPFreeData( exchange->buf );
}
#if PGP_DEBUG_PRINT
static void dhPrintBuffer(pgpDHExchangeRef exchange ) {
PGPUInt32 i;
for( i=0; i<exchange->bufSize; i++ ) {
fprintf( stderr, "%02x", exchange->buf[i] );
}
}
#endif
/* initialize DL DH exchange */
static PGPError dhInitDL( PGPContextRef context, PGPByte group, pgpDHExchangeRef *exchange ) {
PGPError err;
PGPByte *secretX = NULL;
PGPSize secretXsize;
DHExchange *e;
(void)group;
*exchange = NULL;
e = PGPNewData( PGPPeekContextMemoryMgr(context), sizeof(DHExchange), 0 );
if( !e )
return kPGPError_OutOfMemory;
pgpClearMemory( e, sizeof(*e) );
e->ctx = context;
e->mem = PGPPeekContextMemoryMgr(context);
e->is_initiator = TRUE;
err = PGPNewBigNum( e->ctx, TRUE /* secure */, &e->x );
if( IsntPGPError(err) )
err = PGPNewBigNum( e->ctx, FALSE, &e->t );
if( IsntPGPError(err) )
err = PGPNewBigNum( e->ctx, FALSE, &e->gy );
if( IsntPGPError(err) )
err = PGPNewBigNum( e->ctx, FALSE, &e->p );
if( IsntPGPError(err) )
err = PGPNewBigNum( e->ctx, FALSE, &e->g );
/* initialize generator to 2 */
if( IsntPGPError(err) )
err = PGPBigNumSetQ( e->g, 2 );
if( IsntPGPError(err) )
err = PGPBigNumInsertBigEndianBytes( e->p, mod1024bytesG0, 0, sizeof(mod1024bytesG0) );
if( IsntPGPError(err) ) {
e->sizeInTransit = sizeof(mod1024bytesG0);
e->buf = PGPNewData( e->mem, e->sizeInTransit, 0 );
}
if( IsPGPError(err) || e->x==NULL || e->g==NULL || e->p==NULL ||
e->t==NULL || e->gy==NULL )
{
dhFree( e );
return kPGPError_OutOfMemory;
}
(void)PGPDiscreteLogExponentBits( e->sizeInTransit, (PGPUInt32 *)&secretXsize );
secretXsize = (secretXsize*3/2 + 7) / 8;
secretX = PGPNewSecureData( e->mem, secretXsize, 0 );
if( IsNull( secretX ) ) {
dhFree(e);
return kPGPError_OutOfMemory;
}
(void)PGPGlobalRandomPoolAddSystemState();
err = PGPContextGetRandomBytes( e->ctx, secretX, secretXsize );
if( IsntPGPError(err) )
err = PGPBigNumInsertBigEndianBytes( e->x, secretX, 0, secretXsize );
if( secretX )
(void)PGPFreeData( secretX );
if( IsntPGPError(err) )
*exchange = e;
return err;
}
static PGPError dhImportGY(pgpDHExchangeRef exchange, const PGPByte *gy, PGPSize size ) {
PGPError err;
if( !gy || !size)
return kPGPError_CorruptData;
while( gy[0] == 0 && size ) {
gy++;
size--;
}
if( size > exchange->sizeInTransit )
return kPGPError_CorruptData;
err = PGPBigNumInsertBigEndianBytes( exchange->gy, gy, 0, size );
if( IsPGPError(err) )
return err;
if( PGPBigNumCompareQ( exchange->gy, 0xffff ) < 0 )
return kPGPError_BadParams;
// TODO: small group check
return err;
}
/* Perform DH step 1 with internal structures, i.e. g (op) x,
*/
static PGPError
dhGenerate1( pgpDHExchangeRef exchange )
{
PGPError err = kPGPError_NoErr;
err = PGPBigNumExpMod(exchange->g, exchange->x, exchange->p, exchange->t );
if( IsntPGPError(err) )
err = PGPBigNumExtractBigEndianBytes( exchange->t, exchange->buf, 0, exchange->sizeInTransit );
if( IsntPGPError(err) )
exchange->bufSize = exchange->sizeInTransit;
return err;
}
/* Perform DH step 2 with internal structures, i.e. (g (op) y) (op) x,
*/
static PGPError
dhGenerate2( pgpDHExchangeRef exchange )
{
PGPError err = kPGPError_NoErr;
err = PGPBigNumExpMod(exchange->gy, exchange->x, exchange->p, exchange->t );
if( IsntPGPError(err) )
err = PGPBigNumExtractBigEndianBytes( exchange->t, exchange->buf, 0, exchange->sizeInTransit );
if( IsntPGPError(err) )
exchange->bufSize = exchange->sizeInTransit;
return err;
}
static PGPByte *dhBuf( pgpDHExchangeRef exchange ) {
if( !exchange )
return NULL;
return exchange->buf;
}
static PGPSize dhBufSize( pgpDHExchangeRef exchange ) {
if( !exchange )
return 0;
return exchange->bufSize;
}
/* add PKCS 5 padding to the null-terminated string */
static PGPInt32 pkcs5Padding( PGPByte *s, PGPSize blockSize ) {
const PGPSize len = strlen( s )+1; /* include '\0' */
PGPByte paddingSize = (PGPByte)(blockSize - len % blockSize);
PGPUInt32 i = paddingSize;
s += len;
while(i--)
*(s++) = paddingSize;
*s = '\0';
return paddingSize;
}
static PGPError parseHttpUrl( const PGPByte *url,
PGPInternetAddress *addr_out, PGPUInt16 *port_out,
PGPByte host_port_buf[kPGPLANet_ReceiveSize],
PGPByte resource_buf[kPGPLANet_ReceiveSize] )
{
const static PGPUInt16 defPortInt = 80;
PGPByte http[] = "http://";
PGPByte url_buf[256];
PGPError err = kPGPError_NoErr;
PGPByte *resource;
PGPByte *port;
PGPByte root[] = "/";
PGPUInt16 portInt;
PGPHostEntry *host;
pgpClearMemory( addr_out, sizeof(*addr_out) );
*port_out = 0;
resource_buf[0] = '\0';
host_port_buf[0] = '\0';
strncpy( url_buf, url, sizeof(url_buf) );
url_buf[sizeof(url_buf)-1] = '\0';
url = url_buf;
if( strnicmp( url, http, sizeof(http)-1 ) != 0 )
return kPGPError_FeatureNotAvailable;
url += sizeof(http)-1;
resource = strchr( url, '/' );
if( !resource )
strcpy( resource_buf, root );
else
strcpy( resource_buf, resource );
*resource = '\0'; /* cut resource part */
/* cut and initialize the port number, if present */
port = strchr( url, ':' );
if( port == NULL )
portInt = defPortInt;
else {
portInt = atoi( port+1 );
*port = '\0';
}
host = PGPGetHostByName( url );
sprintf( host_port_buf, "%s:%d", url, portInt );
if( host==NULL ) {
resource_buf[0] = '\0';
return PGPGetLastSocketsError();
}
*addr_out = *((PGPInternetAddress*)
host->h_addr_list[0]);
*port_out = portInt;
return err;
}
static PGPError createSocket( PGPInternetAddress ipAddress, PGPUInt16 port, PGPSocketRef *socket )
{
PGPSocketRef s;
PGPSocketAddressInternet address;
PGPInt32 socketResult;
*socket = kInvalidPGPSocketRef;
s = PGPOpenSocket( kPGPAddressFamilyInternet,
kPGPSocketTypeStream,
kPGPTCPProtocol);
if(s == kInvalidPGPSocketRef)
return PGPGetLastSocketsError();
address.sin_family = kPGPAddressFamilyInternet;
address.sin_port = PGPHostToNetShort(port);
address.sin_addr = ipAddress;
socketResult = PGPConnect( s, (PGPSocketAddress *) &address, sizeof(address));
if (socketResult == kPGPSockets_Error) {
PGPCloseSocket(s);
return PGPGetLastSocketsError();
}
*socket = s;
return kPGPError_NoErr;
}
/*
XXX
static PGPError addParam( PGPByte *buffer, PGPSize totalSize,
PGPByte *name, PGPByte *value )
{
PGPSize l = strlen( buffer );
PGPSize avail = totalSize - l;
if( totalSize < l )
return kPGPError_CorruptData;
if( strlen(name)+strlen(value)+3 > avail )
return kPGPError_BufferTooSmall;
sprintf( buffer+l, "&%s=%s", name, value );
return kPGPError_NoErr;
}
*/
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -