⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 encode.c

📁 vc环境下的pgp源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* encode.c - ber output encoding routines */
/*
 * Copyright (c) 1990 Regents of the University of Michigan.
 * All rights reserved.
 *
 * Redistribution and use in source and binary forms are permitted
 * provided that this notice is preserved and that due credit is given
 * to the University of Michigan at Ann Arbor. The name of the University
 * may not be used to endorse or promote products derived from this
 * software without specific prior written permission. This software
 * is provided ``as is'' without express or implied warranty.
 */

#include <stdio.h>

#if PGPSOCKETSLDAP	/* jason */
#include "pgpSocketsLDAP.h"

#else
#ifdef MACOS
#include <stdlib.h>
#include <stdarg.h>
#include "macos.h"
#else /* MACOS */
#if defined(NeXT) || defined(VMS)
#include <stdlib.h>
#else /* next || vms */
#include <malloc.h>
#endif /* next || vms */
#if defined(PGPSOCKETSLDAP) || defined( BC31 ) || defined( _WIN32 )
#include <stdarg.h>
#else /* BC31 || _WIN32 */
#include <varargs.h>
#endif /* BC31 || _WIN32 */
#include <sys/types.h>
#ifndef WIN32			/* marcd */
#include <sys/socket.h>
#include <netinet/in.h>
#endif
#ifdef PCNFS
#include <tklib.h>
#endif /* PCNFS */
#endif /* MACOS */
#ifndef VMS
#include <memory.h>
#endif
#ifdef WIN32
#include <winsock.h>
#endif
#endif /* PGPSOCKETSLDAP */

#include <string.h>
#include "lber.h"

#if defined( DOS ) || defined( xx_WIN32 )	/* marcd */
#include "msdos.h"
#endif /* DOS */

#ifdef NEEDPROTOS
static int ber_put_len( BerElement *ber, unsigned long len, int nosos );
static int ber_start_seqorset( BerElement *ber, unsigned long tag );
static int ber_put_seqorset( BerElement *ber );
static int ber_put_int_or_enum( BerElement *ber, long num, unsigned long tag );
#endif /* NEEDPROTOS */


static int
ber_calc_taglen( unsigned long tag )
{
	int	i;
	long	mask;

	/* find the first non-all-zero byte in the tag */
	for ( i = sizeof(long) - 1; i > 0; i-- ) {
		mask = (0xffL << (i * 8));
		/* not all zero */
		if ( tag & mask )
			break;
	}

	return( i + 1 );
}

static int
ber_put_tag( BerElement	*ber, unsigned long tag, int nosos )
{
	int		taglen;
	unsigned long	ntag;

	taglen = ber_calc_taglen( tag );

	ntag = LBER_HTONL( tag );

	return( ber_write( ber, ((char *) &ntag) + sizeof(long) - taglen,
	    taglen, nosos ) );
}

static int
ber_calc_lenlen( unsigned long len )
{
	/*
	 * short len if it's less than 128 - one byte giving the len,
	 * with bit 8 0.
	 */

	if ( len <= 0x7F )
		return( 1 );

	/*
	 * long len otherwise - one byte with bit 8 set, giving the
	 * length of the length, followed by the length itself.
	 */

	if ( len <= 0xFF )
		return( 2 );
	if ( len <= 0xFFFFL )
		return( 3 );
	if ( len <= 0xFFFFFFL )
		return( 4 );

	return( 5 );
}

static int
ber_put_len( BerElement *ber, unsigned long len, int nosos )
{
	int		i;
	char		lenlen;
	long		mask;
	unsigned long	netlen;

	/*
	 * short len if it's less than 128 - one byte giving the len,
	 * with bit 8 0.
	 */

	if ( len <= 127 ) {
		netlen = LBER_HTONL( len );
		return( ber_write( ber, (char *) &netlen + sizeof(long) - 1,
		    1, nosos ) );
	}

	/*
	 * long len otherwise - one byte with bit 8 set, giving the
	 * length of the length, followed by the length itself.
	 */

	/* find the first non-all-zero byte */
	for ( i = sizeof(long) - 1; i > 0; i-- ) {
		mask = (0xffL << (i * 8));
		/* not all zero */
		if ( len & mask )
			break;
	}
	lenlen = ++i;
	if ( lenlen > 4 )
		return( -1 );
	lenlen |= 0x80;

	/* write the length of the length */
	if ( ber_write( ber, &lenlen, 1, nosos ) != 1 )
		return( -1 );

	/* write the length itself */
	netlen = LBER_HTONL( len );
	if ( ber_write( ber, (char *) &netlen + (sizeof(long) - i), i, nosos )
	    != i )
		return( -1 );

	return( i + 1 );
}

static int
ber_put_int_or_enum( BerElement *ber, long num, unsigned long tag )
{
	int	i, sign, taglen;
	int	len, lenlen;
	long	netnum, mask;

	sign = (num < 0);

	/*
	 * high bit is set - look for first non-all-one byte
	 * high bit is clear - look for first non-all-zero byte
	 */
	for ( i = sizeof(long) - 1; i > 0; i-- ) {
		mask = (0xffL << (i * 8));

		if ( sign ) {
			/* not all ones */
			if ( (num & mask) != mask )
				break;
		} else {
			/* not all zero */
			if ( num & mask )
				break;
		}
	}

	/*
	 * we now have the "leading byte".  if the high bit on this
	 * byte matches the sign bit, we need to "back up" a byte.
	 */
	mask = (num & (0x80L << (i * 8)));
	if ( (mask && !sign) || (sign && !mask) )
		i++;

	len = i + 1;

	if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )
		return( -1 );

	if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 )
		return( -1 );
	i++;
	netnum = LBER_HTONL( num );
	if ( ber_write( ber, (char *) &netnum + (sizeof(long) - i), i, 0 )
	   != i )
		return( -1 );

	/* length of tag + length + contents */
	return( taglen + lenlen + i );
}

int
ber_put_enum( BerElement *ber, long num, unsigned long tag )
{
	if ( tag == LBER_DEFAULT )
		tag = LBER_ENUMERATED;

	return( ber_put_int_or_enum( ber, num, tag ) );
}

int
ber_put_int( BerElement *ber, long num, unsigned long tag )
{
	if ( tag == LBER_DEFAULT )
		tag = LBER_INTEGER;

	return( ber_put_int_or_enum( ber, num, tag ) );
}

int
ber_put_ostring( BerElement *ber, char *str, unsigned long len,
	unsigned long tag )
{
	int	taglen, lenlen, rc;
#ifdef STR_TRANSLATION
	int	free_str;
#endif /* STR_TRANSLATION */

	if ( tag == LBER_DEFAULT )
		tag = LBER_OCTETSTRING;

	if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )
		return( -1 );

#ifdef STR_TRANSLATION
	if ( len > 0 && ( ber->ber_options & LBER_TRANSLATE_STRINGS ) != 0 &&
	    ber->ber_encode_translate_proc != NULL ) {
		if ( (*(ber->ber_encode_translate_proc))( &str, &len, 0 )
		    != 0 ) {
			return( -1 );
		}
		free_str = 1;
	} else {
		free_str = 0;
	}
#endif /* STR_TRANSLATION */

	if ( (lenlen = ber_put_len( ber, len, 0 )) == -1 ||
		ber_write( ber, str, len, 0 ) != (long) len ) {
		rc = -1;
	} else {
		/* return length of tag + length + contents */
		rc = taglen + lenlen + len;
	}

#ifdef STR_TRANSLATION
	if ( free_str ) {
		free( str );
	}
#endif /* STR_TRANSLATION */

	return( rc );
}

int
ber_put_string( BerElement *ber, char *str, unsigned long tag )
{
	return( ber_put_ostring( ber, str, strlen( str ), tag ));
}

int
ber_put_bitstring( BerElement *ber, char *str,
	unsigned long blen /* in bits */, unsigned long tag )
{
	int		taglen, lenlen, len;
	unsigned char	unusedbits;

	if ( tag == LBER_DEFAULT )
		tag = LBER_BITSTRING;

	if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )
		return( -1 );

	len = ( blen + 7 ) / 8;
	unusedbits = (unsigned char) (len * 8 - blen);
	if ( (lenlen = ber_put_len( ber, len + 1, 0 )) == -1 )
		return( -1 );

	if ( ber_write( ber, (char *)&unusedbits, 1, 0 ) != 1 )
		return( -1 );

	if ( ber_write( ber, str, len, 0 ) != len )
		return( -1 );

	/* return length of tag + length + unused bit count + contents */
	return( taglen + 1 + lenlen + len );
}

int
ber_put_null( BerElement *ber, unsigned long tag )
{
	int	taglen;

	if ( tag == LBER_DEFAULT )
		tag = LBER_NULL;

	if ( (taglen = ber_put_tag( ber, tag, 0 )) == -1 )
		return( -1 );

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -