Update OpenSSL to version 1.0.1s
(cherry picked from commitc860574d8band commit2cbd850979)
This commit is contained in:
@ -1,2 +1,5 @@
|
||||
|
||||
|
||||
#ifndef MK1MF_BUILD
|
||||
# define CFLAGS "-DB_ENDIAN"
|
||||
# define PLATFORM "macos"
|
||||
# define DATE "Sun Feb 27 19:44:16 MET 2000"
|
||||
#endif
|
||||
|
||||
@ -1,4 +1,6 @@
|
||||
/* $LP: LPlib/source/LPdir_win.c,v 1.1 2004/06/14 10:07:56 _cvs_levitte Exp $ */
|
||||
/*
|
||||
* $LP: LPlib/source/LPdir_win.c,v 1.1 2004/06/14 10:07:56 _cvs_levitte Exp $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
|
||||
* All rights reserved.
|
||||
@ -26,17 +28,20 @@
|
||||
*/
|
||||
|
||||
#ifndef LPDIR_H
|
||||
#include "LPdir.h"
|
||||
# include "LPdir.h"
|
||||
#endif
|
||||
|
||||
struct LP_dir_context_st { void *dummy; };
|
||||
struct LP_dir_context_st {
|
||||
void *dummy;
|
||||
};
|
||||
const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int LP_find_file_end(LP_DIR_CTX **ctx)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
/* $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp $ */
|
||||
/*
|
||||
* $LP: LPlib/source/LPdir_unix.c,v 1.11 2004/09/23 22:07:22 _cvs_levitte Exp
|
||||
* $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
|
||||
* All rights reserved.
|
||||
@ -11,7 +14,7 @@
|
||||
* 2. 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.
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@ -33,95 +36,91 @@
|
||||
#include <dirent.h>
|
||||
#include <errno.h>
|
||||
#ifndef LPDIR_H
|
||||
#include "LPdir.h"
|
||||
# include "LPdir.h"
|
||||
#endif
|
||||
|
||||
/* The POSIXly macro for the maximum number of characters in a file path
|
||||
is NAME_MAX. However, some operating systems use PATH_MAX instead.
|
||||
Therefore, it seems natural to first check for PATH_MAX and use that,
|
||||
and if it doesn't exist, use NAME_MAX. */
|
||||
/*
|
||||
* The POSIXly macro for the maximum number of characters in a file path is
|
||||
* NAME_MAX. However, some operating systems use PATH_MAX instead.
|
||||
* Therefore, it seems natural to first check for PATH_MAX and use that, and
|
||||
* if it doesn't exist, use NAME_MAX.
|
||||
*/
|
||||
#if defined(PATH_MAX)
|
||||
# define LP_ENTRY_SIZE PATH_MAX
|
||||
#elif defined(NAME_MAX)
|
||||
# define LP_ENTRY_SIZE NAME_MAX
|
||||
#endif
|
||||
|
||||
/* Of course, there's the possibility that neither PATH_MAX nor NAME_MAX
|
||||
exist. It's also possible that NAME_MAX exists but is define to a
|
||||
very small value (HP-UX offers 14), so we need to check if we got a
|
||||
result, and if it meets a minimum standard, and create or change it
|
||||
if not. */
|
||||
/*
|
||||
* Of course, there's the possibility that neither PATH_MAX nor NAME_MAX
|
||||
* exist. It's also possible that NAME_MAX exists but is define to a very
|
||||
* small value (HP-UX offers 14), so we need to check if we got a result, and
|
||||
* if it meets a minimum standard, and create or change it if not.
|
||||
*/
|
||||
#if !defined(LP_ENTRY_SIZE) || LP_ENTRY_SIZE<255
|
||||
# undef LP_ENTRY_SIZE
|
||||
# define LP_ENTRY_SIZE 255
|
||||
#endif
|
||||
|
||||
struct LP_dir_context_st
|
||||
{
|
||||
DIR *dir;
|
||||
char entry_name[LP_ENTRY_SIZE+1];
|
||||
struct LP_dir_context_st {
|
||||
DIR *dir;
|
||||
char entry_name[LP_ENTRY_SIZE + 1];
|
||||
};
|
||||
|
||||
const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
|
||||
{
|
||||
struct dirent *direntry = NULL;
|
||||
struct dirent *direntry = NULL;
|
||||
|
||||
if (ctx == NULL || directory == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
if (ctx == NULL || directory == NULL) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if (*ctx == NULL)
|
||||
{
|
||||
*ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
|
||||
if (*ctx == NULL)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
memset(*ctx, '\0', sizeof(LP_DIR_CTX));
|
||||
errno = 0;
|
||||
if (*ctx == NULL) {
|
||||
*ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
|
||||
if (*ctx == NULL) {
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
memset(*ctx, '\0', sizeof(LP_DIR_CTX));
|
||||
|
||||
(*ctx)->dir = opendir(directory);
|
||||
if ((*ctx)->dir == NULL)
|
||||
{
|
||||
int save_errno = errno; /* Probably not needed, but I'm paranoid */
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
errno = save_errno;
|
||||
return 0;
|
||||
}
|
||||
(*ctx)->dir = opendir(directory);
|
||||
if ((*ctx)->dir == NULL) {
|
||||
int save_errno = errno; /* Probably not needed, but I'm paranoid */
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
errno = save_errno;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
direntry = readdir((*ctx)->dir);
|
||||
if (direntry == NULL)
|
||||
{
|
||||
return 0;
|
||||
direntry = readdir((*ctx)->dir);
|
||||
if (direntry == NULL) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
strncpy((*ctx)->entry_name, direntry->d_name, sizeof((*ctx)->entry_name) - 1);
|
||||
(*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
|
||||
return (*ctx)->entry_name;
|
||||
strncpy((*ctx)->entry_name, direntry->d_name,
|
||||
sizeof((*ctx)->entry_name) - 1);
|
||||
(*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
|
||||
return (*ctx)->entry_name;
|
||||
}
|
||||
|
||||
int LP_find_file_end(LP_DIR_CTX **ctx)
|
||||
{
|
||||
if (ctx != NULL && *ctx != NULL)
|
||||
{
|
||||
int ret = closedir((*ctx)->dir);
|
||||
if (ctx != NULL && *ctx != NULL) {
|
||||
int ret = closedir((*ctx)->dir);
|
||||
|
||||
free(*ctx);
|
||||
switch (ret)
|
||||
{
|
||||
case 0:
|
||||
return 1;
|
||||
case -1:
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
free(*ctx);
|
||||
switch (ret) {
|
||||
case 0:
|
||||
return 1;
|
||||
case -1:
|
||||
return 0;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
/* $LP: LPlib/source/LPdir_vms.c,v 1.20 2004/08/26 13:36:05 _cvs_levitte Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
|
||||
* All rights reserved.
|
||||
@ -11,7 +10,7 @@
|
||||
* 2. 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.
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@ -38,169 +37,159 @@
|
||||
#include <str$routines.h>
|
||||
#include <stsdef.h>
|
||||
#ifndef LPDIR_H
|
||||
#include "LPdir.h"
|
||||
# include "LPdir.h"
|
||||
#endif
|
||||
#include "vms_rms.h"
|
||||
|
||||
/* Some compiler options hide EVMSERR. */
|
||||
#ifndef EVMSERR
|
||||
# define EVMSERR 65535 /* error for non-translatable VMS errors */
|
||||
# define EVMSERR 65535 /* error for non-translatable VMS errors */
|
||||
#endif
|
||||
|
||||
struct LP_dir_context_st
|
||||
{
|
||||
unsigned long VMS_context;
|
||||
char filespec[ NAMX_MAXRSS+ 1];
|
||||
char result[ NAMX_MAXRSS+ 1];
|
||||
struct dsc$descriptor_d filespec_dsc;
|
||||
struct dsc$descriptor_d result_dsc;
|
||||
struct LP_dir_context_st {
|
||||
unsigned long VMS_context;
|
||||
char filespec[NAMX_MAXRSS + 1];
|
||||
char result[NAMX_MAXRSS + 1];
|
||||
struct dsc$descriptor_d filespec_dsc;
|
||||
struct dsc$descriptor_d result_dsc;
|
||||
};
|
||||
|
||||
const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
|
||||
{
|
||||
int status;
|
||||
char *p, *r;
|
||||
size_t l;
|
||||
unsigned long flags = 0;
|
||||
int status;
|
||||
char *p, *r;
|
||||
size_t l;
|
||||
unsigned long flags = 0;
|
||||
|
||||
/* Arrange 32-bit pointer to (copied) string storage, if needed. */
|
||||
#if __INITIAL_POINTER_SIZE == 64
|
||||
# pragma pointer_size save
|
||||
# pragma pointer_size 32
|
||||
char *ctx_filespec_32p;
|
||||
char *ctx_filespec_32p;
|
||||
# pragma pointer_size restore
|
||||
char ctx_filespec_32[ NAMX_MAXRSS+ 1];
|
||||
#endif /* __INITIAL_POINTER_SIZE == 64 */
|
||||
char ctx_filespec_32[NAMX_MAXRSS + 1];
|
||||
#endif /* __INITIAL_POINTER_SIZE == 64 */
|
||||
|
||||
#ifdef NAML$C_MAXRSS
|
||||
flags |= LIB$M_FIL_LONG_NAMES;
|
||||
flags |= LIB$M_FIL_LONG_NAMES;
|
||||
#endif
|
||||
|
||||
if (ctx == NULL || directory == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
if (ctx == NULL || directory == NULL) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if (*ctx == NULL)
|
||||
{
|
||||
size_t filespeclen = strlen(directory);
|
||||
char *filespec = NULL;
|
||||
errno = 0;
|
||||
if (*ctx == NULL) {
|
||||
size_t filespeclen = strlen(directory);
|
||||
char *filespec = NULL;
|
||||
|
||||
/* MUST be a VMS directory specification! Let's estimate if it is. */
|
||||
if (directory[filespeclen-1] != ']'
|
||||
&& directory[filespeclen-1] != '>'
|
||||
&& directory[filespeclen-1] != ':')
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
if (filespeclen == 0) {
|
||||
errno = ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
filespeclen += 4; /* "*.*;" */
|
||||
/* MUST be a VMS directory specification! Let's estimate if it is. */
|
||||
if (directory[filespeclen - 1] != ']'
|
||||
&& directory[filespeclen - 1] != '>'
|
||||
&& directory[filespeclen - 1] != ':') {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (filespeclen > NAMX_MAXRSS)
|
||||
{
|
||||
errno = ENAMETOOLONG;
|
||||
return 0;
|
||||
}
|
||||
filespeclen += 4; /* "*.*;" */
|
||||
|
||||
*ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
|
||||
if (*ctx == NULL)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
memset(*ctx, '\0', sizeof(LP_DIR_CTX));
|
||||
if (filespeclen > NAMX_MAXRSS) {
|
||||
errno = ENAMETOOLONG;
|
||||
return 0;
|
||||
}
|
||||
|
||||
strcpy((*ctx)->filespec,directory);
|
||||
strcat((*ctx)->filespec,"*.*;");
|
||||
*ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
|
||||
if (*ctx == NULL) {
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
memset(*ctx, '\0', sizeof(LP_DIR_CTX));
|
||||
|
||||
strcpy((*ctx)->filespec, directory);
|
||||
strcat((*ctx)->filespec, "*.*;");
|
||||
|
||||
/* Arrange 32-bit pointer to (copied) string storage, if needed. */
|
||||
#if __INITIAL_POINTER_SIZE == 64
|
||||
# define CTX_FILESPEC ctx_filespec_32p
|
||||
/* Copy the file name to storage with a 32-bit pointer. */
|
||||
ctx_filespec_32p = ctx_filespec_32;
|
||||
strcpy( ctx_filespec_32p, (*ctx)->filespec);
|
||||
#else /* __INITIAL_POINTER_SIZE == 64 */
|
||||
strcpy(ctx_filespec_32p, (*ctx)->filespec);
|
||||
#else /* __INITIAL_POINTER_SIZE == 64 */
|
||||
# define CTX_FILESPEC (*ctx)->filespec
|
||||
#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
|
||||
#endif /* __INITIAL_POINTER_SIZE == 64 [else] */
|
||||
|
||||
(*ctx)->filespec_dsc.dsc$w_length = filespeclen;
|
||||
(*ctx)->filespec_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
|
||||
(*ctx)->filespec_dsc.dsc$b_class = DSC$K_CLASS_S;
|
||||
(*ctx)->filespec_dsc.dsc$a_pointer = CTX_FILESPEC;
|
||||
(*ctx)->filespec_dsc.dsc$w_length = filespeclen;
|
||||
(*ctx)->filespec_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
|
||||
(*ctx)->filespec_dsc.dsc$b_class = DSC$K_CLASS_S;
|
||||
(*ctx)->filespec_dsc.dsc$a_pointer = CTX_FILESPEC;
|
||||
}
|
||||
|
||||
(*ctx)->result_dsc.dsc$w_length = 0;
|
||||
(*ctx)->result_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
|
||||
(*ctx)->result_dsc.dsc$b_class = DSC$K_CLASS_D;
|
||||
(*ctx)->result_dsc.dsc$a_pointer = 0;
|
||||
(*ctx)->result_dsc.dsc$w_length = 0;
|
||||
(*ctx)->result_dsc.dsc$b_dtype = DSC$K_DTYPE_T;
|
||||
(*ctx)->result_dsc.dsc$b_class = DSC$K_CLASS_D;
|
||||
(*ctx)->result_dsc.dsc$a_pointer = 0;
|
||||
|
||||
status = lib$find_file(&(*ctx)->filespec_dsc, &(*ctx)->result_dsc,
|
||||
&(*ctx)->VMS_context, 0, 0, 0, &flags);
|
||||
status = lib$find_file(&(*ctx)->filespec_dsc, &(*ctx)->result_dsc,
|
||||
&(*ctx)->VMS_context, 0, 0, 0, &flags);
|
||||
|
||||
if (status == RMS$_NMF)
|
||||
{
|
||||
errno = 0;
|
||||
vaxc$errno = status;
|
||||
return NULL;
|
||||
if (status == RMS$_NMF) {
|
||||
errno = 0;
|
||||
vaxc$errno = status;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if(!$VMS_STATUS_SUCCESS(status))
|
||||
{
|
||||
errno = EVMSERR;
|
||||
vaxc$errno = status;
|
||||
return NULL;
|
||||
if (!$VMS_STATUS_SUCCESS(status)) {
|
||||
errno = EVMSERR;
|
||||
vaxc$errno = status;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Quick, cheap and dirty way to discard any device and directory,
|
||||
since we only want file names */
|
||||
l = (*ctx)->result_dsc.dsc$w_length;
|
||||
p = (*ctx)->result_dsc.dsc$a_pointer;
|
||||
r = p;
|
||||
for (; *p; p++)
|
||||
{
|
||||
if (*p == '^' && p[1] != '\0') /* Take care of ODS-5 escapes */
|
||||
{
|
||||
p++;
|
||||
}
|
||||
else if (*p == ':' || *p == '>' || *p == ']')
|
||||
{
|
||||
l -= p + 1 - r;
|
||||
r = p + 1;
|
||||
}
|
||||
else if (*p == ';')
|
||||
{
|
||||
l = p - r;
|
||||
break;
|
||||
}
|
||||
/*
|
||||
* Quick, cheap and dirty way to discard any device and directory, since
|
||||
* we only want file names
|
||||
*/
|
||||
l = (*ctx)->result_dsc.dsc$w_length;
|
||||
p = (*ctx)->result_dsc.dsc$a_pointer;
|
||||
r = p;
|
||||
for (; *p; p++) {
|
||||
if (*p == '^' && p[1] != '\0') { /* Take care of ODS-5 escapes */
|
||||
p++;
|
||||
} else if (*p == ':' || *p == '>' || *p == ']') {
|
||||
l -= p + 1 - r;
|
||||
r = p + 1;
|
||||
} else if (*p == ';') {
|
||||
l = p - r;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
strncpy((*ctx)->result, r, l);
|
||||
(*ctx)->result[l] = '\0';
|
||||
str$free1_dx(&(*ctx)->result_dsc);
|
||||
strncpy((*ctx)->result, r, l);
|
||||
(*ctx)->result[l] = '\0';
|
||||
str$free1_dx(&(*ctx)->result_dsc);
|
||||
|
||||
return (*ctx)->result;
|
||||
return (*ctx)->result;
|
||||
}
|
||||
|
||||
int LP_find_file_end(LP_DIR_CTX **ctx)
|
||||
{
|
||||
if (ctx != NULL && *ctx != NULL)
|
||||
{
|
||||
int status = lib$find_file_end(&(*ctx)->VMS_context);
|
||||
if (ctx != NULL && *ctx != NULL) {
|
||||
int status = lib$find_file_end(&(*ctx)->VMS_context);
|
||||
|
||||
free(*ctx);
|
||||
free(*ctx);
|
||||
|
||||
if(!$VMS_STATUS_SUCCESS(status))
|
||||
{
|
||||
errno = EVMSERR;
|
||||
vaxc$errno = status;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
if (!$VMS_STATUS_SUCCESS(status)) {
|
||||
errno = EVMSERR;
|
||||
vaxc$errno = status;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,3 @@
|
||||
/* $LP: LPlib/source/LPdir_win.c,v 1.10 2004/08/26 13:36:05 _cvs_levitte Exp $ */
|
||||
/*
|
||||
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
|
||||
* All rights reserved.
|
||||
@ -11,7 +10,7 @@
|
||||
* 2. 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.
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@ -27,127 +26,145 @@
|
||||
#include <windows.h>
|
||||
#include <tchar.h>
|
||||
#ifndef LPDIR_H
|
||||
#include "LPdir.h"
|
||||
# include "LPdir.h"
|
||||
#endif
|
||||
|
||||
/* We're most likely overcautious here, but let's reserve for
|
||||
broken WinCE headers and explicitly opt for UNICODE call.
|
||||
Keep in mind that our WinCE builds are compiled with -DUNICODE
|
||||
[as well as -D_UNICODE]. */
|
||||
/*
|
||||
* We're most likely overcautious here, but let's reserve for broken WinCE
|
||||
* headers and explicitly opt for UNICODE call. Keep in mind that our WinCE
|
||||
* builds are compiled with -DUNICODE [as well as -D_UNICODE].
|
||||
*/
|
||||
#if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
|
||||
# define FindFirstFile FindFirstFileW
|
||||
#endif
|
||||
#if defined(LP_SYS_WINCE) && !defined(FindFirstFile)
|
||||
#if defined(LP_SYS_WINCE) && !defined(FindNextFile)
|
||||
# define FindNextFile FindNextFileW
|
||||
#endif
|
||||
|
||||
#ifndef NAME_MAX
|
||||
#define NAME_MAX 255
|
||||
# define NAME_MAX 255
|
||||
#endif
|
||||
|
||||
struct LP_dir_context_st
|
||||
{
|
||||
WIN32_FIND_DATA ctx;
|
||||
HANDLE handle;
|
||||
char entry_name[NAME_MAX+1];
|
||||
struct LP_dir_context_st {
|
||||
WIN32_FIND_DATA ctx;
|
||||
HANDLE handle;
|
||||
char entry_name[NAME_MAX + 1];
|
||||
};
|
||||
|
||||
const char *LP_find_file(LP_DIR_CTX **ctx, const char *directory)
|
||||
{
|
||||
if (ctx == NULL || directory == NULL)
|
||||
{
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
if (ctx == NULL || directory == NULL) {
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
errno = 0;
|
||||
if (*ctx == NULL)
|
||||
{
|
||||
*ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
|
||||
if (*ctx == NULL)
|
||||
{
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
memset(*ctx, '\0', sizeof(LP_DIR_CTX));
|
||||
errno = 0;
|
||||
if (*ctx == NULL) {
|
||||
const char *extdir = directory;
|
||||
char *extdirbuf = NULL;
|
||||
size_t dirlen = strlen(directory);
|
||||
|
||||
if (sizeof(TCHAR) != sizeof(char))
|
||||
{
|
||||
TCHAR *wdir = NULL;
|
||||
/* len_0 denotes string length *with* trailing 0 */
|
||||
size_t index = 0,len_0 = strlen(directory) + 1;
|
||||
if (dirlen == 0) {
|
||||
errno = ENOENT;
|
||||
return 0;
|
||||
}
|
||||
|
||||
wdir = (TCHAR *)malloc(len_0 * sizeof(TCHAR));
|
||||
if (wdir == NULL)
|
||||
{
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
*ctx = (LP_DIR_CTX *)malloc(sizeof(LP_DIR_CTX));
|
||||
if (*ctx == NULL) {
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
memset(*ctx, '\0', sizeof(LP_DIR_CTX));
|
||||
|
||||
if (directory[dirlen - 1] != '*') {
|
||||
extdirbuf = (char *)malloc(dirlen + 3);
|
||||
if (extdirbuf == NULL) {
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
if (directory[dirlen - 1] != '/' && directory[dirlen - 1] != '\\')
|
||||
extdir = strcat(strcpy(extdirbuf, directory), "/*");
|
||||
else
|
||||
extdir = strcat(strcpy(extdirbuf, directory), "*");
|
||||
}
|
||||
|
||||
if (sizeof(TCHAR) != sizeof(char)) {
|
||||
TCHAR *wdir = NULL;
|
||||
/* len_0 denotes string length *with* trailing 0 */
|
||||
size_t index = 0, len_0 = strlen(extdir) + 1;
|
||||
|
||||
wdir = (TCHAR *)calloc(len_0, sizeof(TCHAR));
|
||||
if (wdir == NULL) {
|
||||
if (extdirbuf != NULL) {
|
||||
free(extdirbuf);
|
||||
}
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
errno = ENOMEM;
|
||||
return 0;
|
||||
}
|
||||
#ifdef LP_MULTIBYTE_AVAILABLE
|
||||
if (!MultiByteToWideChar
|
||||
(CP_ACP, 0, extdir, len_0, (WCHAR *)wdir, len_0))
|
||||
#endif
|
||||
for (index = 0; index < len_0; index++)
|
||||
wdir[index] = (TCHAR)extdir[index];
|
||||
|
||||
(*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
|
||||
|
||||
free(wdir);
|
||||
} else {
|
||||
(*ctx)->handle = FindFirstFile((TCHAR *)extdir, &(*ctx)->ctx);
|
||||
}
|
||||
if (extdirbuf != NULL) {
|
||||
free(extdirbuf);
|
||||
}
|
||||
|
||||
if ((*ctx)->handle == INVALID_HANDLE_VALUE) {
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
} else {
|
||||
if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE) {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
if (sizeof(TCHAR) != sizeof(char)) {
|
||||
TCHAR *wdir = (*ctx)->ctx.cFileName;
|
||||
size_t index, len_0 = 0;
|
||||
|
||||
while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1))
|
||||
len_0++;
|
||||
len_0++;
|
||||
|
||||
#ifdef LP_MULTIBYTE_AVAILABLE
|
||||
if (!MultiByteToWideChar(CP_ACP, 0, directory, len_0, (WCHAR *)wdir, len_0))
|
||||
if (!WideCharToMultiByte
|
||||
(CP_ACP, 0, (WCHAR *)wdir, len_0, (*ctx)->entry_name,
|
||||
sizeof((*ctx)->entry_name), NULL, 0))
|
||||
#endif
|
||||
for (index = 0; index < len_0; index++)
|
||||
wdir[index] = (TCHAR)directory[index];
|
||||
for (index = 0; index < len_0; index++)
|
||||
(*ctx)->entry_name[index] = (char)wdir[index];
|
||||
} else
|
||||
strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName,
|
||||
sizeof((*ctx)->entry_name) - 1);
|
||||
|
||||
(*ctx)->handle = FindFirstFile(wdir, &(*ctx)->ctx);
|
||||
(*ctx)->entry_name[sizeof((*ctx)->entry_name) - 1] = '\0';
|
||||
|
||||
free(wdir);
|
||||
}
|
||||
else
|
||||
(*ctx)->handle = FindFirstFile((TCHAR *)directory, &(*ctx)->ctx);
|
||||
|
||||
if ((*ctx)->handle == INVALID_HANDLE_VALUE)
|
||||
{
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (FindNextFile((*ctx)->handle, &(*ctx)->ctx) == FALSE)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (sizeof(TCHAR) != sizeof(char))
|
||||
{
|
||||
TCHAR *wdir = (*ctx)->ctx.cFileName;
|
||||
size_t index, len_0 = 0;
|
||||
|
||||
while (wdir[len_0] && len_0 < (sizeof((*ctx)->entry_name) - 1)) len_0++;
|
||||
len_0++;
|
||||
|
||||
#ifdef LP_MULTIBYTE_AVAILABLE
|
||||
if (!WideCharToMultiByte(CP_ACP, 0, (WCHAR *)wdir, len_0, (*ctx)->entry_name,
|
||||
sizeof((*ctx)->entry_name), NULL, 0))
|
||||
#endif
|
||||
for (index = 0; index < len_0; index++)
|
||||
(*ctx)->entry_name[index] = (char)wdir[index];
|
||||
}
|
||||
else
|
||||
strncpy((*ctx)->entry_name, (const char *)(*ctx)->ctx.cFileName,
|
||||
sizeof((*ctx)->entry_name)-1);
|
||||
|
||||
(*ctx)->entry_name[sizeof((*ctx)->entry_name)-1] = '\0';
|
||||
|
||||
return (*ctx)->entry_name;
|
||||
return (*ctx)->entry_name;
|
||||
}
|
||||
|
||||
int LP_find_file_end(LP_DIR_CTX **ctx)
|
||||
{
|
||||
if (ctx != NULL && *ctx != NULL)
|
||||
{
|
||||
FindClose((*ctx)->handle);
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
return 1;
|
||||
if (ctx != NULL && *ctx != NULL) {
|
||||
FindClose((*ctx)->handle);
|
||||
free(*ctx);
|
||||
*ctx = NULL;
|
||||
return 1;
|
||||
}
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
errno = EINVAL;
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
/* $LP: LPlib/source/LPdir_win32.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp $ */
|
||||
/*
|
||||
* $LP: LPlib/source/LPdir_win32.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp
|
||||
* $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
|
||||
* All rights reserved.
|
||||
@ -11,7 +14,7 @@
|
||||
* 2. 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.
|
||||
*
|
||||
*
|
||||
* 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
|
||||
|
||||
@ -1,4 +1,7 @@
|
||||
/* $LP: LPlib/source/LPdir_wince.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp $ */
|
||||
/*
|
||||
* $LP: LPlib/source/LPdir_wince.c,v 1.3 2004/08/26 13:36:05 _cvs_levitte Exp
|
||||
* $
|
||||
*/
|
||||
/*
|
||||
* Copyright (c) 2004, Richard Levitte <richard@levitte.org>
|
||||
* All rights reserved.
|
||||
@ -11,7 +14,7 @@
|
||||
* 2. 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.
|
||||
*
|
||||
*
|
||||
* 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
|
||||
@ -26,6 +29,8 @@
|
||||
*/
|
||||
|
||||
#define LP_SYS_WINCE
|
||||
/* We might want to define LP_MULTIBYTE_AVAILABLE here. It's currently
|
||||
under investigation what the exact conditions would be */
|
||||
/*
|
||||
* We might want to define LP_MULTIBYTE_AVAILABLE here. It's currently under
|
||||
* investigation what the exact conditions would be
|
||||
*/
|
||||
#include "LPdir_win.c"
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* crypto/aes/aes_cbc.c -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* crypto/aes/aes_cbc.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
@ -7,7 +7,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -53,11 +53,14 @@
|
||||
#include <openssl/modes.h>
|
||||
|
||||
void AES_cbc_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t len, const AES_KEY *key,
|
||||
unsigned char *ivec, const int enc) {
|
||||
size_t len, const AES_KEY *key,
|
||||
unsigned char *ivec, const int enc)
|
||||
{
|
||||
|
||||
if (enc)
|
||||
CRYPTO_cbc128_encrypt(in,out,len,key,ivec,(block128_f)AES_encrypt);
|
||||
else
|
||||
CRYPTO_cbc128_decrypt(in,out,len,key,ivec,(block128_f)AES_decrypt);
|
||||
if (enc)
|
||||
CRYPTO_cbc128_encrypt(in, out, len, key, ivec,
|
||||
(block128_f) AES_encrypt);
|
||||
else
|
||||
CRYPTO_cbc128_decrypt(in, out, len, key, ivec,
|
||||
(block128_f) AES_decrypt);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* crypto/aes/aes_cfb.c -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* crypto/aes/aes_cfb.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
@ -7,7 +7,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -52,30 +52,34 @@
|
||||
#include <openssl/aes.h>
|
||||
#include <openssl/modes.h>
|
||||
|
||||
/* The input and output encrypted as though 128bit cfb mode is being
|
||||
* used. The extra state information to record how much of the
|
||||
* 128bit block we have used is contained in *num;
|
||||
/*
|
||||
* The input and output encrypted as though 128bit cfb mode is being used.
|
||||
* The extra state information to record how much of the 128bit block we have
|
||||
* used is contained in *num;
|
||||
*/
|
||||
|
||||
void AES_cfb128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char *ivec, int *num, const int enc) {
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char *ivec, int *num, const int enc)
|
||||
{
|
||||
|
||||
CRYPTO_cfb128_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
|
||||
CRYPTO_cfb128_encrypt(in, out, length, key, ivec, num, enc,
|
||||
(block128_f) AES_encrypt);
|
||||
}
|
||||
|
||||
/* N.B. This expects the input to be packed, MS bit first */
|
||||
void AES_cfb1_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char *ivec, int *num, const int enc)
|
||||
{
|
||||
CRYPTO_cfb128_1_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
|
||||
}
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char *ivec, int *num, const int enc)
|
||||
{
|
||||
CRYPTO_cfb128_1_encrypt(in, out, length, key, ivec, num, enc,
|
||||
(block128_f) AES_encrypt);
|
||||
}
|
||||
|
||||
void AES_cfb8_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char *ivec, int *num, const int enc)
|
||||
{
|
||||
CRYPTO_cfb128_8_encrypt(in,out,length,key,ivec,num,enc,(block128_f)AES_encrypt);
|
||||
}
|
||||
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char *ivec, int *num, const int enc)
|
||||
{
|
||||
CRYPTO_cfb128_8_encrypt(in, out, length, key, ivec, num, enc,
|
||||
(block128_f) AES_encrypt);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* crypto/aes/aes_core.c -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* crypto/aes/aes_core.c */
|
||||
/**
|
||||
* rijndael-alg-fst.c
|
||||
*
|
||||
@ -40,7 +40,7 @@
|
||||
#include "aes_locl.h"
|
||||
|
||||
#ifndef AES_ASM
|
||||
/*
|
||||
/*-
|
||||
Te0[x] = S [x].[02, 01, 01, 03];
|
||||
Te1[x] = S [x].[03, 02, 01, 01];
|
||||
Te2[x] = S [x].[01, 03, 02, 01];
|
||||
@ -617,161 +617,163 @@ static const u8 Td4[256] = {
|
||||
0xe1U, 0x69U, 0x14U, 0x63U, 0x55U, 0x21U, 0x0cU, 0x7dU,
|
||||
};
|
||||
static const u32 rcon[] = {
|
||||
0x01000000, 0x02000000, 0x04000000, 0x08000000,
|
||||
0x10000000, 0x20000000, 0x40000000, 0x80000000,
|
||||
0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
|
||||
0x01000000, 0x02000000, 0x04000000, 0x08000000,
|
||||
0x10000000, 0x20000000, 0x40000000, 0x80000000,
|
||||
0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
|
||||
};
|
||||
|
||||
/**
|
||||
* Expand the cipher key into the encryption key schedule.
|
||||
*/
|
||||
int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key) {
|
||||
AES_KEY *key)
|
||||
{
|
||||
|
||||
u32 *rk;
|
||||
int i = 0;
|
||||
u32 temp;
|
||||
u32 *rk;
|
||||
int i = 0;
|
||||
u32 temp;
|
||||
|
||||
if (!userKey || !key)
|
||||
return -1;
|
||||
if (bits != 128 && bits != 192 && bits != 256)
|
||||
return -2;
|
||||
if (!userKey || !key)
|
||||
return -1;
|
||||
if (bits != 128 && bits != 192 && bits != 256)
|
||||
return -2;
|
||||
|
||||
rk = key->rd_key;
|
||||
rk = key->rd_key;
|
||||
|
||||
if (bits==128)
|
||||
key->rounds = 10;
|
||||
else if (bits==192)
|
||||
key->rounds = 12;
|
||||
else
|
||||
key->rounds = 14;
|
||||
if (bits==128)
|
||||
key->rounds = 10;
|
||||
else if (bits==192)
|
||||
key->rounds = 12;
|
||||
else
|
||||
key->rounds = 14;
|
||||
|
||||
rk[0] = GETU32(userKey );
|
||||
rk[1] = GETU32(userKey + 4);
|
||||
rk[2] = GETU32(userKey + 8);
|
||||
rk[3] = GETU32(userKey + 12);
|
||||
if (bits == 128) {
|
||||
while (1) {
|
||||
temp = rk[3];
|
||||
rk[4] = rk[0] ^
|
||||
(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
|
||||
(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(temp ) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(temp >> 24) ] & 0x000000ff) ^
|
||||
rcon[i];
|
||||
rk[5] = rk[1] ^ rk[4];
|
||||
rk[6] = rk[2] ^ rk[5];
|
||||
rk[7] = rk[3] ^ rk[6];
|
||||
if (++i == 10) {
|
||||
return 0;
|
||||
}
|
||||
rk += 4;
|
||||
}
|
||||
}
|
||||
rk[4] = GETU32(userKey + 16);
|
||||
rk[5] = GETU32(userKey + 20);
|
||||
if (bits == 192) {
|
||||
while (1) {
|
||||
temp = rk[ 5];
|
||||
rk[ 6] = rk[ 0] ^
|
||||
(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
|
||||
(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(temp ) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(temp >> 24) ] & 0x000000ff) ^
|
||||
rcon[i];
|
||||
rk[ 7] = rk[ 1] ^ rk[ 6];
|
||||
rk[ 8] = rk[ 2] ^ rk[ 7];
|
||||
rk[ 9] = rk[ 3] ^ rk[ 8];
|
||||
if (++i == 8) {
|
||||
return 0;
|
||||
}
|
||||
rk[10] = rk[ 4] ^ rk[ 9];
|
||||
rk[11] = rk[ 5] ^ rk[10];
|
||||
rk += 6;
|
||||
}
|
||||
}
|
||||
rk[6] = GETU32(userKey + 24);
|
||||
rk[7] = GETU32(userKey + 28);
|
||||
if (bits == 256) {
|
||||
while (1) {
|
||||
temp = rk[ 7];
|
||||
rk[ 8] = rk[ 0] ^
|
||||
(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
|
||||
(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(temp ) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(temp >> 24) ] & 0x000000ff) ^
|
||||
rcon[i];
|
||||
rk[ 9] = rk[ 1] ^ rk[ 8];
|
||||
rk[10] = rk[ 2] ^ rk[ 9];
|
||||
rk[11] = rk[ 3] ^ rk[10];
|
||||
if (++i == 7) {
|
||||
return 0;
|
||||
}
|
||||
temp = rk[11];
|
||||
rk[12] = rk[ 4] ^
|
||||
(Te2[(temp >> 24) ] & 0xff000000) ^
|
||||
(Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(temp ) & 0xff] & 0x000000ff);
|
||||
rk[13] = rk[ 5] ^ rk[12];
|
||||
rk[14] = rk[ 6] ^ rk[13];
|
||||
rk[15] = rk[ 7] ^ rk[14];
|
||||
rk[0] = GETU32(userKey );
|
||||
rk[1] = GETU32(userKey + 4);
|
||||
rk[2] = GETU32(userKey + 8);
|
||||
rk[3] = GETU32(userKey + 12);
|
||||
if (bits == 128) {
|
||||
while (1) {
|
||||
temp = rk[3];
|
||||
rk[4] = rk[0] ^
|
||||
(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
|
||||
(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(temp ) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(temp >> 24) ] & 0x000000ff) ^
|
||||
rcon[i];
|
||||
rk[5] = rk[1] ^ rk[4];
|
||||
rk[6] = rk[2] ^ rk[5];
|
||||
rk[7] = rk[3] ^ rk[6];
|
||||
if (++i == 10) {
|
||||
return 0;
|
||||
}
|
||||
rk += 4;
|
||||
}
|
||||
}
|
||||
rk[4] = GETU32(userKey + 16);
|
||||
rk[5] = GETU32(userKey + 20);
|
||||
if (bits == 192) {
|
||||
while (1) {
|
||||
temp = rk[ 5];
|
||||
rk[ 6] = rk[ 0] ^
|
||||
(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
|
||||
(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(temp ) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(temp >> 24) ] & 0x000000ff) ^
|
||||
rcon[i];
|
||||
rk[ 7] = rk[ 1] ^ rk[ 6];
|
||||
rk[ 8] = rk[ 2] ^ rk[ 7];
|
||||
rk[ 9] = rk[ 3] ^ rk[ 8];
|
||||
if (++i == 8) {
|
||||
return 0;
|
||||
}
|
||||
rk[10] = rk[ 4] ^ rk[ 9];
|
||||
rk[11] = rk[ 5] ^ rk[10];
|
||||
rk += 6;
|
||||
}
|
||||
}
|
||||
rk[6] = GETU32(userKey + 24);
|
||||
rk[7] = GETU32(userKey + 28);
|
||||
if (bits == 256) {
|
||||
while (1) {
|
||||
temp = rk[ 7];
|
||||
rk[ 8] = rk[ 0] ^
|
||||
(Te2[(temp >> 16) & 0xff] & 0xff000000) ^
|
||||
(Te3[(temp >> 8) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(temp ) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(temp >> 24) ] & 0x000000ff) ^
|
||||
rcon[i];
|
||||
rk[ 9] = rk[ 1] ^ rk[ 8];
|
||||
rk[10] = rk[ 2] ^ rk[ 9];
|
||||
rk[11] = rk[ 3] ^ rk[10];
|
||||
if (++i == 7) {
|
||||
return 0;
|
||||
}
|
||||
temp = rk[11];
|
||||
rk[12] = rk[ 4] ^
|
||||
(Te2[(temp >> 24) ] & 0xff000000) ^
|
||||
(Te3[(temp >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(temp >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(temp ) & 0xff] & 0x000000ff);
|
||||
rk[13] = rk[ 5] ^ rk[12];
|
||||
rk[14] = rk[ 6] ^ rk[13];
|
||||
rk[15] = rk[ 7] ^ rk[14];
|
||||
|
||||
rk += 8;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
rk += 8;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the cipher key into the decryption key schedule.
|
||||
*/
|
||||
int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key) {
|
||||
AES_KEY *key)
|
||||
{
|
||||
|
||||
u32 *rk;
|
||||
int i, j, status;
|
||||
u32 temp;
|
||||
u32 *rk;
|
||||
int i, j, status;
|
||||
u32 temp;
|
||||
|
||||
/* first, start with an encryption schedule */
|
||||
status = private_AES_set_encrypt_key(userKey, bits, key);
|
||||
if (status < 0)
|
||||
return status;
|
||||
/* first, start with an encryption schedule */
|
||||
status = private_AES_set_encrypt_key(userKey, bits, key);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
rk = key->rd_key;
|
||||
rk = key->rd_key;
|
||||
|
||||
/* invert the order of the round keys: */
|
||||
for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
|
||||
temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
|
||||
temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
|
||||
temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
|
||||
temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
|
||||
}
|
||||
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
|
||||
for (i = 1; i < (key->rounds); i++) {
|
||||
rk += 4;
|
||||
rk[0] =
|
||||
Td0[Te1[(rk[0] >> 24) ] & 0xff] ^
|
||||
Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^
|
||||
Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^
|
||||
Td3[Te1[(rk[0] ) & 0xff] & 0xff];
|
||||
rk[1] =
|
||||
Td0[Te1[(rk[1] >> 24) ] & 0xff] ^
|
||||
Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^
|
||||
Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^
|
||||
Td3[Te1[(rk[1] ) & 0xff] & 0xff];
|
||||
rk[2] =
|
||||
Td0[Te1[(rk[2] >> 24) ] & 0xff] ^
|
||||
Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^
|
||||
Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^
|
||||
Td3[Te1[(rk[2] ) & 0xff] & 0xff];
|
||||
rk[3] =
|
||||
Td0[Te1[(rk[3] >> 24) ] & 0xff] ^
|
||||
Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^
|
||||
Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^
|
||||
Td3[Te1[(rk[3] ) & 0xff] & 0xff];
|
||||
}
|
||||
return 0;
|
||||
/* invert the order of the round keys: */
|
||||
for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
|
||||
temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
|
||||
temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
|
||||
temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
|
||||
temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
|
||||
}
|
||||
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
|
||||
for (i = 1; i < (key->rounds); i++) {
|
||||
rk += 4;
|
||||
rk[0] =
|
||||
Td0[Te1[(rk[0] >> 24) ] & 0xff] ^
|
||||
Td1[Te1[(rk[0] >> 16) & 0xff] & 0xff] ^
|
||||
Td2[Te1[(rk[0] >> 8) & 0xff] & 0xff] ^
|
||||
Td3[Te1[(rk[0] ) & 0xff] & 0xff];
|
||||
rk[1] =
|
||||
Td0[Te1[(rk[1] >> 24) ] & 0xff] ^
|
||||
Td1[Te1[(rk[1] >> 16) & 0xff] & 0xff] ^
|
||||
Td2[Te1[(rk[1] >> 8) & 0xff] & 0xff] ^
|
||||
Td3[Te1[(rk[1] ) & 0xff] & 0xff];
|
||||
rk[2] =
|
||||
Td0[Te1[(rk[2] >> 24) ] & 0xff] ^
|
||||
Td1[Te1[(rk[2] >> 16) & 0xff] & 0xff] ^
|
||||
Td2[Te1[(rk[2] >> 8) & 0xff] & 0xff] ^
|
||||
Td3[Te1[(rk[2] ) & 0xff] & 0xff];
|
||||
rk[3] =
|
||||
Td0[Te1[(rk[3] >> 24) ] & 0xff] ^
|
||||
Td1[Te1[(rk[3] >> 16) & 0xff] & 0xff] ^
|
||||
Td2[Te1[(rk[3] >> 8) & 0xff] & 0xff] ^
|
||||
Td3[Te1[(rk[3] ) & 0xff] & 0xff];
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/*
|
||||
@ -779,71 +781,71 @@ int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
* in and out can overlap
|
||||
*/
|
||||
void AES_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key) {
|
||||
const AES_KEY *key) {
|
||||
|
||||
const u32 *rk;
|
||||
u32 s0, s1, s2, s3, t0, t1, t2, t3;
|
||||
const u32 *rk;
|
||||
u32 s0, s1, s2, s3, t0, t1, t2, t3;
|
||||
#ifndef FULL_UNROLL
|
||||
int r;
|
||||
int r;
|
||||
#endif /* ?FULL_UNROLL */
|
||||
|
||||
assert(in && out && key);
|
||||
rk = key->rd_key;
|
||||
assert(in && out && key);
|
||||
rk = key->rd_key;
|
||||
|
||||
/*
|
||||
* map byte array block to cipher state
|
||||
* and add initial round key:
|
||||
*/
|
||||
s0 = GETU32(in ) ^ rk[0];
|
||||
s1 = GETU32(in + 4) ^ rk[1];
|
||||
s2 = GETU32(in + 8) ^ rk[2];
|
||||
s3 = GETU32(in + 12) ^ rk[3];
|
||||
/*
|
||||
* map byte array block to cipher state
|
||||
* and add initial round key:
|
||||
*/
|
||||
s0 = GETU32(in ) ^ rk[0];
|
||||
s1 = GETU32(in + 4) ^ rk[1];
|
||||
s2 = GETU32(in + 8) ^ rk[2];
|
||||
s3 = GETU32(in + 12) ^ rk[3];
|
||||
#ifdef FULL_UNROLL
|
||||
/* round 1: */
|
||||
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
|
||||
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
|
||||
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
|
||||
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
|
||||
/* round 2: */
|
||||
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
|
||||
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
|
||||
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
|
||||
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
|
||||
/* round 3: */
|
||||
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
|
||||
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
|
||||
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
|
||||
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
|
||||
/* round 4: */
|
||||
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
|
||||
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
|
||||
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
|
||||
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
|
||||
/* round 5: */
|
||||
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
|
||||
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
|
||||
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
|
||||
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
|
||||
/* round 6: */
|
||||
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
|
||||
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
|
||||
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
|
||||
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
|
||||
/* round 7: */
|
||||
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
|
||||
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
|
||||
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
|
||||
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
|
||||
/* round 8: */
|
||||
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
|
||||
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
|
||||
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
|
||||
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
|
||||
/* round 9: */
|
||||
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
|
||||
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
|
||||
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
|
||||
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
|
||||
/* round 1: */
|
||||
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[ 4];
|
||||
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[ 5];
|
||||
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[ 6];
|
||||
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[ 7];
|
||||
/* round 2: */
|
||||
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[ 8];
|
||||
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[ 9];
|
||||
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[10];
|
||||
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[11];
|
||||
/* round 3: */
|
||||
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[12];
|
||||
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[13];
|
||||
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[14];
|
||||
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[15];
|
||||
/* round 4: */
|
||||
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[16];
|
||||
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[17];
|
||||
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[18];
|
||||
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[19];
|
||||
/* round 5: */
|
||||
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[20];
|
||||
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[21];
|
||||
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[22];
|
||||
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[23];
|
||||
/* round 6: */
|
||||
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[24];
|
||||
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[25];
|
||||
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[26];
|
||||
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[27];
|
||||
/* round 7: */
|
||||
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[28];
|
||||
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[29];
|
||||
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[30];
|
||||
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[31];
|
||||
/* round 8: */
|
||||
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[32];
|
||||
s1 = Te0[t1 >> 24] ^ Te1[(t2 >> 16) & 0xff] ^ Te2[(t3 >> 8) & 0xff] ^ Te3[t0 & 0xff] ^ rk[33];
|
||||
s2 = Te0[t2 >> 24] ^ Te1[(t3 >> 16) & 0xff] ^ Te2[(t0 >> 8) & 0xff] ^ Te3[t1 & 0xff] ^ rk[34];
|
||||
s3 = Te0[t3 >> 24] ^ Te1[(t0 >> 16) & 0xff] ^ Te2[(t1 >> 8) & 0xff] ^ Te3[t2 & 0xff] ^ rk[35];
|
||||
/* round 9: */
|
||||
t0 = Te0[s0 >> 24] ^ Te1[(s1 >> 16) & 0xff] ^ Te2[(s2 >> 8) & 0xff] ^ Te3[s3 & 0xff] ^ rk[36];
|
||||
t1 = Te0[s1 >> 24] ^ Te1[(s2 >> 16) & 0xff] ^ Te2[(s3 >> 8) & 0xff] ^ Te3[s0 & 0xff] ^ rk[37];
|
||||
t2 = Te0[s2 >> 24] ^ Te1[(s3 >> 16) & 0xff] ^ Te2[(s0 >> 8) & 0xff] ^ Te3[s1 & 0xff] ^ rk[38];
|
||||
t3 = Te0[s3 >> 24] ^ Te1[(s0 >> 16) & 0xff] ^ Te2[(s1 >> 8) & 0xff] ^ Te3[s2 & 0xff] ^ rk[39];
|
||||
if (key->rounds > 10) {
|
||||
/* round 10: */
|
||||
s0 = Te0[t0 >> 24] ^ Te1[(t1 >> 16) & 0xff] ^ Te2[(t2 >> 8) & 0xff] ^ Te3[t3 & 0xff] ^ rk[40];
|
||||
@ -932,37 +934,37 @@ void AES_encrypt(const unsigned char *in, unsigned char *out,
|
||||
}
|
||||
#endif /* ?FULL_UNROLL */
|
||||
/*
|
||||
* apply last round and
|
||||
* map cipher state to byte array block:
|
||||
*/
|
||||
s0 =
|
||||
(Te2[(t0 >> 24) ] & 0xff000000) ^
|
||||
(Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(t3 ) & 0xff] & 0x000000ff) ^
|
||||
rk[0];
|
||||
PUTU32(out , s0);
|
||||
s1 =
|
||||
(Te2[(t1 >> 24) ] & 0xff000000) ^
|
||||
(Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(t0 ) & 0xff] & 0x000000ff) ^
|
||||
rk[1];
|
||||
PUTU32(out + 4, s1);
|
||||
s2 =
|
||||
(Te2[(t2 >> 24) ] & 0xff000000) ^
|
||||
(Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(t1 ) & 0xff] & 0x000000ff) ^
|
||||
rk[2];
|
||||
PUTU32(out + 8, s2);
|
||||
s3 =
|
||||
(Te2[(t3 >> 24) ] & 0xff000000) ^
|
||||
(Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(t2 ) & 0xff] & 0x000000ff) ^
|
||||
rk[3];
|
||||
PUTU32(out + 12, s3);
|
||||
* apply last round and
|
||||
* map cipher state to byte array block:
|
||||
*/
|
||||
s0 =
|
||||
(Te2[(t0 >> 24) ] & 0xff000000) ^
|
||||
(Te3[(t1 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(t2 >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(t3 ) & 0xff] & 0x000000ff) ^
|
||||
rk[0];
|
||||
PUTU32(out , s0);
|
||||
s1 =
|
||||
(Te2[(t1 >> 24) ] & 0xff000000) ^
|
||||
(Te3[(t2 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(t3 >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(t0 ) & 0xff] & 0x000000ff) ^
|
||||
rk[1];
|
||||
PUTU32(out + 4, s1);
|
||||
s2 =
|
||||
(Te2[(t2 >> 24) ] & 0xff000000) ^
|
||||
(Te3[(t3 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(t0 >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(t1 ) & 0xff] & 0x000000ff) ^
|
||||
rk[2];
|
||||
PUTU32(out + 8, s2);
|
||||
s3 =
|
||||
(Te2[(t3 >> 24) ] & 0xff000000) ^
|
||||
(Te3[(t0 >> 16) & 0xff] & 0x00ff0000) ^
|
||||
(Te0[(t1 >> 8) & 0xff] & 0x0000ff00) ^
|
||||
(Te1[(t2 ) & 0xff] & 0x000000ff) ^
|
||||
rk[3];
|
||||
PUTU32(out + 12, s3);
|
||||
}
|
||||
|
||||
/*
|
||||
@ -970,21 +972,22 @@ void AES_encrypt(const unsigned char *in, unsigned char *out,
|
||||
* in and out can overlap
|
||||
*/
|
||||
void AES_decrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key) {
|
||||
const AES_KEY *key)
|
||||
{
|
||||
|
||||
const u32 *rk;
|
||||
u32 s0, s1, s2, s3, t0, t1, t2, t3;
|
||||
const u32 *rk;
|
||||
u32 s0, s1, s2, s3, t0, t1, t2, t3;
|
||||
#ifndef FULL_UNROLL
|
||||
int r;
|
||||
int r;
|
||||
#endif /* ?FULL_UNROLL */
|
||||
|
||||
assert(in && out && key);
|
||||
rk = key->rd_key;
|
||||
assert(in && out && key);
|
||||
rk = key->rd_key;
|
||||
|
||||
/*
|
||||
* map byte array block to cipher state
|
||||
* and add initial round key:
|
||||
*/
|
||||
/*
|
||||
* map byte array block to cipher state
|
||||
* and add initial round key:
|
||||
*/
|
||||
s0 = GETU32(in ) ^ rk[0];
|
||||
s1 = GETU32(in + 4) ^ rk[1];
|
||||
s2 = GETU32(in + 8) ^ rk[2];
|
||||
@ -1059,7 +1062,7 @@ void AES_decrypt(const unsigned char *in, unsigned char *out,
|
||||
t3 = Td0[s3 >> 24] ^ Td1[(s2 >> 16) & 0xff] ^ Td2[(s1 >> 8) & 0xff] ^ Td3[s0 & 0xff] ^ rk[55];
|
||||
}
|
||||
}
|
||||
rk += key->rounds << 2;
|
||||
rk += key->rounds << 2;
|
||||
#else /* !FULL_UNROLL */
|
||||
/*
|
||||
* Nr - 1 full rounds:
|
||||
@ -1123,37 +1126,37 @@ void AES_decrypt(const unsigned char *in, unsigned char *out,
|
||||
}
|
||||
#endif /* ?FULL_UNROLL */
|
||||
/*
|
||||
* apply last round and
|
||||
* map cipher state to byte array block:
|
||||
*/
|
||||
s0 =
|
||||
(Td4[(t0 >> 24) ] << 24) ^
|
||||
(Td4[(t3 >> 16) & 0xff] << 16) ^
|
||||
(Td4[(t2 >> 8) & 0xff] << 8) ^
|
||||
(Td4[(t1 ) & 0xff]) ^
|
||||
rk[0];
|
||||
PUTU32(out , s0);
|
||||
s1 =
|
||||
(Td4[(t1 >> 24) ] << 24) ^
|
||||
(Td4[(t0 >> 16) & 0xff] << 16) ^
|
||||
(Td4[(t3 >> 8) & 0xff] << 8) ^
|
||||
(Td4[(t2 ) & 0xff]) ^
|
||||
rk[1];
|
||||
PUTU32(out + 4, s1);
|
||||
s2 =
|
||||
(Td4[(t2 >> 24) ] << 24) ^
|
||||
(Td4[(t1 >> 16) & 0xff] << 16) ^
|
||||
(Td4[(t0 >> 8) & 0xff] << 8) ^
|
||||
(Td4[(t3 ) & 0xff]) ^
|
||||
rk[2];
|
||||
PUTU32(out + 8, s2);
|
||||
s3 =
|
||||
(Td4[(t3 >> 24) ] << 24) ^
|
||||
(Td4[(t2 >> 16) & 0xff] << 16) ^
|
||||
(Td4[(t1 >> 8) & 0xff] << 8) ^
|
||||
(Td4[(t0 ) & 0xff]) ^
|
||||
rk[3];
|
||||
PUTU32(out + 12, s3);
|
||||
* apply last round and
|
||||
* map cipher state to byte array block:
|
||||
*/
|
||||
s0 =
|
||||
((u32)Td4[(t0 >> 24) ] << 24) ^
|
||||
((u32)Td4[(t3 >> 16) & 0xff] << 16) ^
|
||||
((u32)Td4[(t2 >> 8) & 0xff] << 8) ^
|
||||
((u32)Td4[(t1 ) & 0xff]) ^
|
||||
rk[0];
|
||||
PUTU32(out , s0);
|
||||
s1 =
|
||||
((u32)Td4[(t1 >> 24) ] << 24) ^
|
||||
((u32)Td4[(t0 >> 16) & 0xff] << 16) ^
|
||||
((u32)Td4[(t3 >> 8) & 0xff] << 8) ^
|
||||
((u32)Td4[(t2 ) & 0xff]) ^
|
||||
rk[1];
|
||||
PUTU32(out + 4, s1);
|
||||
s2 =
|
||||
((u32)Td4[(t2 >> 24) ] << 24) ^
|
||||
((u32)Td4[(t1 >> 16) & 0xff] << 16) ^
|
||||
((u32)Td4[(t0 >> 8) & 0xff] << 8) ^
|
||||
((u32)Td4[(t3 ) & 0xff]) ^
|
||||
rk[2];
|
||||
PUTU32(out + 8, s2);
|
||||
s3 =
|
||||
((u32)Td4[(t3 >> 24) ] << 24) ^
|
||||
((u32)Td4[(t2 >> 16) & 0xff] << 16) ^
|
||||
((u32)Td4[(t1 >> 8) & 0xff] << 8) ^
|
||||
((u32)Td4[(t0 ) & 0xff]) ^
|
||||
rk[3];
|
||||
PUTU32(out + 12, s3);
|
||||
}
|
||||
|
||||
#else /* AES_ASM */
|
||||
@ -1193,166 +1196,168 @@ static const u8 Te4[256] = {
|
||||
0x41U, 0x99U, 0x2dU, 0x0fU, 0xb0U, 0x54U, 0xbbU, 0x16U
|
||||
};
|
||||
static const u32 rcon[] = {
|
||||
0x01000000, 0x02000000, 0x04000000, 0x08000000,
|
||||
0x10000000, 0x20000000, 0x40000000, 0x80000000,
|
||||
0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
|
||||
0x01000000, 0x02000000, 0x04000000, 0x08000000,
|
||||
0x10000000, 0x20000000, 0x40000000, 0x80000000,
|
||||
0x1B000000, 0x36000000, /* for 128-bit blocks, Rijndael never uses more than 10 rcon values */
|
||||
};
|
||||
|
||||
/**
|
||||
* Expand the cipher key into the encryption key schedule.
|
||||
*/
|
||||
int private_AES_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key) {
|
||||
u32 *rk;
|
||||
AES_KEY *key)
|
||||
{
|
||||
u32 *rk;
|
||||
int i = 0;
|
||||
u32 temp;
|
||||
u32 temp;
|
||||
|
||||
if (!userKey || !key)
|
||||
return -1;
|
||||
if (bits != 128 && bits != 192 && bits != 256)
|
||||
return -2;
|
||||
if (!userKey || !key)
|
||||
return -1;
|
||||
if (bits != 128 && bits != 192 && bits != 256)
|
||||
return -2;
|
||||
|
||||
rk = key->rd_key;
|
||||
rk = key->rd_key;
|
||||
|
||||
if (bits==128)
|
||||
key->rounds = 10;
|
||||
else if (bits==192)
|
||||
key->rounds = 12;
|
||||
else
|
||||
key->rounds = 14;
|
||||
if (bits==128)
|
||||
key->rounds = 10;
|
||||
else if (bits==192)
|
||||
key->rounds = 12;
|
||||
else
|
||||
key->rounds = 14;
|
||||
|
||||
rk[0] = GETU32(userKey );
|
||||
rk[1] = GETU32(userKey + 4);
|
||||
rk[2] = GETU32(userKey + 8);
|
||||
rk[3] = GETU32(userKey + 12);
|
||||
if (bits == 128) {
|
||||
while (1) {
|
||||
temp = rk[3];
|
||||
rk[4] = rk[0] ^
|
||||
(Te4[(temp >> 16) & 0xff] << 24) ^
|
||||
(Te4[(temp >> 8) & 0xff] << 16) ^
|
||||
(Te4[(temp ) & 0xff] << 8) ^
|
||||
(Te4[(temp >> 24) ]) ^
|
||||
rcon[i];
|
||||
rk[5] = rk[1] ^ rk[4];
|
||||
rk[6] = rk[2] ^ rk[5];
|
||||
rk[7] = rk[3] ^ rk[6];
|
||||
if (++i == 10) {
|
||||
return 0;
|
||||
}
|
||||
rk += 4;
|
||||
}
|
||||
}
|
||||
rk[4] = GETU32(userKey + 16);
|
||||
rk[5] = GETU32(userKey + 20);
|
||||
if (bits == 192) {
|
||||
while (1) {
|
||||
temp = rk[ 5];
|
||||
rk[ 6] = rk[ 0] ^
|
||||
(Te4[(temp >> 16) & 0xff] << 24) ^
|
||||
(Te4[(temp >> 8) & 0xff] << 16) ^
|
||||
(Te4[(temp ) & 0xff] << 8) ^
|
||||
(Te4[(temp >> 24) ]) ^
|
||||
rcon[i];
|
||||
rk[ 7] = rk[ 1] ^ rk[ 6];
|
||||
rk[ 8] = rk[ 2] ^ rk[ 7];
|
||||
rk[ 9] = rk[ 3] ^ rk[ 8];
|
||||
if (++i == 8) {
|
||||
return 0;
|
||||
}
|
||||
rk[10] = rk[ 4] ^ rk[ 9];
|
||||
rk[11] = rk[ 5] ^ rk[10];
|
||||
rk += 6;
|
||||
}
|
||||
}
|
||||
rk[6] = GETU32(userKey + 24);
|
||||
rk[7] = GETU32(userKey + 28);
|
||||
if (bits == 256) {
|
||||
while (1) {
|
||||
temp = rk[ 7];
|
||||
rk[ 8] = rk[ 0] ^
|
||||
(Te4[(temp >> 16) & 0xff] << 24) ^
|
||||
(Te4[(temp >> 8) & 0xff] << 16) ^
|
||||
(Te4[(temp ) & 0xff] << 8) ^
|
||||
(Te4[(temp >> 24) ]) ^
|
||||
rcon[i];
|
||||
rk[ 9] = rk[ 1] ^ rk[ 8];
|
||||
rk[10] = rk[ 2] ^ rk[ 9];
|
||||
rk[11] = rk[ 3] ^ rk[10];
|
||||
if (++i == 7) {
|
||||
return 0;
|
||||
}
|
||||
temp = rk[11];
|
||||
rk[12] = rk[ 4] ^
|
||||
(Te4[(temp >> 24) ] << 24) ^
|
||||
(Te4[(temp >> 16) & 0xff] << 16) ^
|
||||
(Te4[(temp >> 8) & 0xff] << 8) ^
|
||||
(Te4[(temp ) & 0xff]);
|
||||
rk[13] = rk[ 5] ^ rk[12];
|
||||
rk[14] = rk[ 6] ^ rk[13];
|
||||
rk[15] = rk[ 7] ^ rk[14];
|
||||
rk[0] = GETU32(userKey );
|
||||
rk[1] = GETU32(userKey + 4);
|
||||
rk[2] = GETU32(userKey + 8);
|
||||
rk[3] = GETU32(userKey + 12);
|
||||
if (bits == 128) {
|
||||
while (1) {
|
||||
temp = rk[3];
|
||||
rk[4] = rk[0] ^
|
||||
((u32)Te4[(temp >> 16) & 0xff] << 24) ^
|
||||
((u32)Te4[(temp >> 8) & 0xff] << 16) ^
|
||||
((u32)Te4[(temp ) & 0xff] << 8) ^
|
||||
((u32)Te4[(temp >> 24) ]) ^
|
||||
rcon[i];
|
||||
rk[5] = rk[1] ^ rk[4];
|
||||
rk[6] = rk[2] ^ rk[5];
|
||||
rk[7] = rk[3] ^ rk[6];
|
||||
if (++i == 10) {
|
||||
return 0;
|
||||
}
|
||||
rk += 4;
|
||||
}
|
||||
}
|
||||
rk[4] = GETU32(userKey + 16);
|
||||
rk[5] = GETU32(userKey + 20);
|
||||
if (bits == 192) {
|
||||
while (1) {
|
||||
temp = rk[ 5];
|
||||
rk[ 6] = rk[ 0] ^
|
||||
((u32)Te4[(temp >> 16) & 0xff] << 24) ^
|
||||
((u32)Te4[(temp >> 8) & 0xff] << 16) ^
|
||||
((u32)Te4[(temp ) & 0xff] << 8) ^
|
||||
((u32)Te4[(temp >> 24) ]) ^
|
||||
rcon[i];
|
||||
rk[ 7] = rk[ 1] ^ rk[ 6];
|
||||
rk[ 8] = rk[ 2] ^ rk[ 7];
|
||||
rk[ 9] = rk[ 3] ^ rk[ 8];
|
||||
if (++i == 8) {
|
||||
return 0;
|
||||
}
|
||||
rk[10] = rk[ 4] ^ rk[ 9];
|
||||
rk[11] = rk[ 5] ^ rk[10];
|
||||
rk += 6;
|
||||
}
|
||||
}
|
||||
rk[6] = GETU32(userKey + 24);
|
||||
rk[7] = GETU32(userKey + 28);
|
||||
if (bits == 256) {
|
||||
while (1) {
|
||||
temp = rk[ 7];
|
||||
rk[ 8] = rk[ 0] ^
|
||||
((u32)Te4[(temp >> 16) & 0xff] << 24) ^
|
||||
((u32)Te4[(temp >> 8) & 0xff] << 16) ^
|
||||
((u32)Te4[(temp ) & 0xff] << 8) ^
|
||||
((u32)Te4[(temp >> 24) ]) ^
|
||||
rcon[i];
|
||||
rk[ 9] = rk[ 1] ^ rk[ 8];
|
||||
rk[10] = rk[ 2] ^ rk[ 9];
|
||||
rk[11] = rk[ 3] ^ rk[10];
|
||||
if (++i == 7) {
|
||||
return 0;
|
||||
}
|
||||
temp = rk[11];
|
||||
rk[12] = rk[ 4] ^
|
||||
((u32)Te4[(temp >> 24) ] << 24) ^
|
||||
((u32)Te4[(temp >> 16) & 0xff] << 16) ^
|
||||
((u32)Te4[(temp >> 8) & 0xff] << 8) ^
|
||||
((u32)Te4[(temp ) & 0xff]);
|
||||
rk[13] = rk[ 5] ^ rk[12];
|
||||
rk[14] = rk[ 6] ^ rk[13];
|
||||
rk[15] = rk[ 7] ^ rk[14];
|
||||
|
||||
rk += 8;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
rk += 8;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Expand the cipher key into the decryption key schedule.
|
||||
*/
|
||||
int private_AES_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key) {
|
||||
AES_KEY *key)
|
||||
{
|
||||
|
||||
u32 *rk;
|
||||
int i, j, status;
|
||||
u32 temp;
|
||||
u32 *rk;
|
||||
int i, j, status;
|
||||
u32 temp;
|
||||
|
||||
/* first, start with an encryption schedule */
|
||||
status = private_AES_set_encrypt_key(userKey, bits, key);
|
||||
if (status < 0)
|
||||
return status;
|
||||
/* first, start with an encryption schedule */
|
||||
status = private_AES_set_encrypt_key(userKey, bits, key);
|
||||
if (status < 0)
|
||||
return status;
|
||||
|
||||
rk = key->rd_key;
|
||||
rk = key->rd_key;
|
||||
|
||||
/* invert the order of the round keys: */
|
||||
for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
|
||||
temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
|
||||
temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
|
||||
temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
|
||||
temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
|
||||
}
|
||||
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
|
||||
for (i = 1; i < (key->rounds); i++) {
|
||||
rk += 4;
|
||||
for (j = 0; j < 4; j++) {
|
||||
u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
|
||||
/* invert the order of the round keys: */
|
||||
for (i = 0, j = 4*(key->rounds); i < j; i += 4, j -= 4) {
|
||||
temp = rk[i ]; rk[i ] = rk[j ]; rk[j ] = temp;
|
||||
temp = rk[i + 1]; rk[i + 1] = rk[j + 1]; rk[j + 1] = temp;
|
||||
temp = rk[i + 2]; rk[i + 2] = rk[j + 2]; rk[j + 2] = temp;
|
||||
temp = rk[i + 3]; rk[i + 3] = rk[j + 3]; rk[j + 3] = temp;
|
||||
}
|
||||
/* apply the inverse MixColumn transform to all round keys but the first and the last: */
|
||||
for (i = 1; i < (key->rounds); i++) {
|
||||
rk += 4;
|
||||
for (j = 0; j < 4; j++) {
|
||||
u32 tp1, tp2, tp4, tp8, tp9, tpb, tpd, tpe, m;
|
||||
|
||||
tp1 = rk[j];
|
||||
m = tp1 & 0x80808080;
|
||||
tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
|
||||
((m - (m >> 7)) & 0x1b1b1b1b);
|
||||
m = tp2 & 0x80808080;
|
||||
tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
|
||||
((m - (m >> 7)) & 0x1b1b1b1b);
|
||||
m = tp4 & 0x80808080;
|
||||
tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
|
||||
((m - (m >> 7)) & 0x1b1b1b1b);
|
||||
tp9 = tp8 ^ tp1;
|
||||
tpb = tp9 ^ tp2;
|
||||
tpd = tp9 ^ tp4;
|
||||
tpe = tp8 ^ tp4 ^ tp2;
|
||||
tp1 = rk[j];
|
||||
m = tp1 & 0x80808080;
|
||||
tp2 = ((tp1 & 0x7f7f7f7f) << 1) ^
|
||||
((m - (m >> 7)) & 0x1b1b1b1b);
|
||||
m = tp2 & 0x80808080;
|
||||
tp4 = ((tp2 & 0x7f7f7f7f) << 1) ^
|
||||
((m - (m >> 7)) & 0x1b1b1b1b);
|
||||
m = tp4 & 0x80808080;
|
||||
tp8 = ((tp4 & 0x7f7f7f7f) << 1) ^
|
||||
((m - (m >> 7)) & 0x1b1b1b1b);
|
||||
tp9 = tp8 ^ tp1;
|
||||
tpb = tp9 ^ tp2;
|
||||
tpd = tp9 ^ tp4;
|
||||
tpe = tp8 ^ tp4 ^ tp2;
|
||||
#if defined(ROTATE)
|
||||
rk[j] = tpe ^ ROTATE(tpd,16) ^
|
||||
ROTATE(tp9,24) ^ ROTATE(tpb,8);
|
||||
rk[j] = tpe ^ ROTATE(tpd,16) ^
|
||||
ROTATE(tp9,24) ^ ROTATE(tpb,8);
|
||||
#else
|
||||
rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
|
||||
(tp9 >> 8) ^ (tp9 << 24) ^
|
||||
(tpb >> 24) ^ (tpb << 8);
|
||||
rk[j] = tpe ^ (tpd >> 16) ^ (tpd << 16) ^
|
||||
(tp9 >> 8) ^ (tp9 << 24) ^
|
||||
(tpb >> 24) ^ (tpb << 8);
|
||||
#endif
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif /* AES_ASM */
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* crypto/aes/aes_ctr.c -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* crypto/aes/aes_ctr.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
@ -7,7 +7,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -53,9 +53,11 @@
|
||||
#include <openssl/modes.h>
|
||||
|
||||
void AES_ctr128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char ivec[AES_BLOCK_SIZE],
|
||||
unsigned char ecount_buf[AES_BLOCK_SIZE],
|
||||
unsigned int *num) {
|
||||
CRYPTO_ctr128_encrypt(in,out,length,key,ivec,ecount_buf,num,(block128_f)AES_encrypt);
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char ivec[AES_BLOCK_SIZE],
|
||||
unsigned char ecount_buf[AES_BLOCK_SIZE],
|
||||
unsigned int *num)
|
||||
{
|
||||
CRYPTO_ctr128_encrypt(in, out, length, key, ivec, ecount_buf, num,
|
||||
(block128_f) AES_encrypt);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* crypto/aes/aes_ecb.c -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* crypto/aes/aes_ecb.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
@ -7,7 +7,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -60,14 +60,14 @@
|
||||
#include "aes_locl.h"
|
||||
|
||||
void AES_ecb_encrypt(const unsigned char *in, unsigned char *out,
|
||||
const AES_KEY *key, const int enc) {
|
||||
const AES_KEY *key, const int enc)
|
||||
{
|
||||
|
||||
assert(in && out && key);
|
||||
assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
|
||||
assert(in && out && key);
|
||||
assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
|
||||
|
||||
if (AES_ENCRYPT == enc)
|
||||
AES_encrypt(in, out, key);
|
||||
else
|
||||
AES_decrypt(in, out, key);
|
||||
if (AES_ENCRYPT == enc)
|
||||
AES_encrypt(in, out, key);
|
||||
else
|
||||
AES_decrypt(in, out, key);
|
||||
}
|
||||
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* crypto/aes/aes_ige.c -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* crypto/aes/aes_ige.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
@ -7,7 +7,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -56,152 +56,147 @@
|
||||
|
||||
#define N_WORDS (AES_BLOCK_SIZE / sizeof(unsigned long))
|
||||
typedef struct {
|
||||
unsigned long data[N_WORDS];
|
||||
unsigned long data[N_WORDS];
|
||||
} aes_block_t;
|
||||
|
||||
/* XXX: probably some better way to do this */
|
||||
#if defined(__i386__) || defined(__x86_64__)
|
||||
#define UNALIGNED_MEMOPS_ARE_FAST 1
|
||||
# define UNALIGNED_MEMOPS_ARE_FAST 1
|
||||
#else
|
||||
#define UNALIGNED_MEMOPS_ARE_FAST 0
|
||||
# define UNALIGNED_MEMOPS_ARE_FAST 0
|
||||
#endif
|
||||
|
||||
#if UNALIGNED_MEMOPS_ARE_FAST
|
||||
#define load_block(d, s) (d) = *(const aes_block_t *)(s)
|
||||
#define store_block(d, s) *(aes_block_t *)(d) = (s)
|
||||
# define load_block(d, s) (d) = *(const aes_block_t *)(s)
|
||||
# define store_block(d, s) *(aes_block_t *)(d) = (s)
|
||||
#else
|
||||
#define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE)
|
||||
#define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE)
|
||||
# define load_block(d, s) memcpy((d).data, (s), AES_BLOCK_SIZE)
|
||||
# define store_block(d, s) memcpy((d), (s).data, AES_BLOCK_SIZE)
|
||||
#endif
|
||||
|
||||
/* N.B. The IV for this mode is _twice_ the block size */
|
||||
|
||||
void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char *ivec, const int enc)
|
||||
{
|
||||
size_t n;
|
||||
size_t len = length;
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char *ivec, const int enc)
|
||||
{
|
||||
size_t n;
|
||||
size_t len = length;
|
||||
|
||||
OPENSSL_assert(in && out && key && ivec);
|
||||
OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
|
||||
OPENSSL_assert((length%AES_BLOCK_SIZE) == 0);
|
||||
OPENSSL_assert(in && out && key && ivec);
|
||||
OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
|
||||
OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);
|
||||
|
||||
len = length / AES_BLOCK_SIZE;
|
||||
len = length / AES_BLOCK_SIZE;
|
||||
|
||||
if (AES_ENCRYPT == enc)
|
||||
{
|
||||
if (in != out &&
|
||||
(UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0))
|
||||
{
|
||||
aes_block_t *ivp = (aes_block_t *)ivec;
|
||||
aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
|
||||
if (AES_ENCRYPT == enc) {
|
||||
if (in != out &&
|
||||
(UNALIGNED_MEMOPS_ARE_FAST
|
||||
|| ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) ==
|
||||
0)) {
|
||||
aes_block_t *ivp = (aes_block_t *) ivec;
|
||||
aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE);
|
||||
|
||||
while (len)
|
||||
{
|
||||
aes_block_t *inp = (aes_block_t *)in;
|
||||
aes_block_t *outp = (aes_block_t *)out;
|
||||
while (len) {
|
||||
aes_block_t *inp = (aes_block_t *) in;
|
||||
aes_block_t *outp = (aes_block_t *) out;
|
||||
|
||||
for(n=0 ; n < N_WORDS; ++n)
|
||||
outp->data[n] = inp->data[n] ^ ivp->data[n];
|
||||
AES_encrypt((unsigned char *)outp->data, (unsigned char *)outp->data, key);
|
||||
for(n=0 ; n < N_WORDS; ++n)
|
||||
outp->data[n] ^= iv2p->data[n];
|
||||
ivp = outp;
|
||||
iv2p = inp;
|
||||
--len;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
|
||||
memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
aes_block_t tmp, tmp2;
|
||||
aes_block_t iv;
|
||||
aes_block_t iv2;
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
outp->data[n] = inp->data[n] ^ ivp->data[n];
|
||||
AES_encrypt((unsigned char *)outp->data,
|
||||
(unsigned char *)outp->data, key);
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
outp->data[n] ^= iv2p->data[n];
|
||||
ivp = outp;
|
||||
iv2p = inp;
|
||||
--len;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
|
||||
memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
|
||||
} else {
|
||||
aes_block_t tmp, tmp2;
|
||||
aes_block_t iv;
|
||||
aes_block_t iv2;
|
||||
|
||||
load_block(iv, ivec);
|
||||
load_block(iv2, ivec + AES_BLOCK_SIZE);
|
||||
load_block(iv, ivec);
|
||||
load_block(iv2, ivec + AES_BLOCK_SIZE);
|
||||
|
||||
while (len)
|
||||
{
|
||||
load_block(tmp, in);
|
||||
for(n=0 ; n < N_WORDS; ++n)
|
||||
tmp2.data[n] = tmp.data[n] ^ iv.data[n];
|
||||
AES_encrypt((unsigned char *)tmp2.data, (unsigned char *)tmp2.data, key);
|
||||
for(n=0 ; n < N_WORDS; ++n)
|
||||
tmp2.data[n] ^= iv2.data[n];
|
||||
store_block(out, tmp2);
|
||||
iv = tmp2;
|
||||
iv2 = tmp;
|
||||
--len;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
memcpy(ivec, iv.data, AES_BLOCK_SIZE);
|
||||
memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (in != out &&
|
||||
(UNALIGNED_MEMOPS_ARE_FAST || ((size_t)in|(size_t)out|(size_t)ivec)%sizeof(long)==0))
|
||||
{
|
||||
aes_block_t *ivp = (aes_block_t *)ivec;
|
||||
aes_block_t *iv2p = (aes_block_t *)(ivec + AES_BLOCK_SIZE);
|
||||
while (len) {
|
||||
load_block(tmp, in);
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
tmp2.data[n] = tmp.data[n] ^ iv.data[n];
|
||||
AES_encrypt((unsigned char *)tmp2.data,
|
||||
(unsigned char *)tmp2.data, key);
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
tmp2.data[n] ^= iv2.data[n];
|
||||
store_block(out, tmp2);
|
||||
iv = tmp2;
|
||||
iv2 = tmp;
|
||||
--len;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
memcpy(ivec, iv.data, AES_BLOCK_SIZE);
|
||||
memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
|
||||
}
|
||||
} else {
|
||||
if (in != out &&
|
||||
(UNALIGNED_MEMOPS_ARE_FAST
|
||||
|| ((size_t)in | (size_t)out | (size_t)ivec) % sizeof(long) ==
|
||||
0)) {
|
||||
aes_block_t *ivp = (aes_block_t *) ivec;
|
||||
aes_block_t *iv2p = (aes_block_t *) (ivec + AES_BLOCK_SIZE);
|
||||
|
||||
while (len)
|
||||
{
|
||||
aes_block_t tmp;
|
||||
aes_block_t *inp = (aes_block_t *)in;
|
||||
aes_block_t *outp = (aes_block_t *)out;
|
||||
while (len) {
|
||||
aes_block_t tmp;
|
||||
aes_block_t *inp = (aes_block_t *) in;
|
||||
aes_block_t *outp = (aes_block_t *) out;
|
||||
|
||||
for(n=0 ; n < N_WORDS; ++n)
|
||||
tmp.data[n] = inp->data[n] ^ iv2p->data[n];
|
||||
AES_decrypt((unsigned char *)tmp.data, (unsigned char *)outp->data, key);
|
||||
for(n=0 ; n < N_WORDS; ++n)
|
||||
outp->data[n] ^= ivp->data[n];
|
||||
ivp = inp;
|
||||
iv2p = outp;
|
||||
--len;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
|
||||
memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
|
||||
}
|
||||
else
|
||||
{
|
||||
aes_block_t tmp, tmp2;
|
||||
aes_block_t iv;
|
||||
aes_block_t iv2;
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
tmp.data[n] = inp->data[n] ^ iv2p->data[n];
|
||||
AES_decrypt((unsigned char *)tmp.data,
|
||||
(unsigned char *)outp->data, key);
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
outp->data[n] ^= ivp->data[n];
|
||||
ivp = inp;
|
||||
iv2p = outp;
|
||||
--len;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
memcpy(ivec, ivp->data, AES_BLOCK_SIZE);
|
||||
memcpy(ivec + AES_BLOCK_SIZE, iv2p->data, AES_BLOCK_SIZE);
|
||||
} else {
|
||||
aes_block_t tmp, tmp2;
|
||||
aes_block_t iv;
|
||||
aes_block_t iv2;
|
||||
|
||||
load_block(iv, ivec);
|
||||
load_block(iv2, ivec + AES_BLOCK_SIZE);
|
||||
load_block(iv, ivec);
|
||||
load_block(iv2, ivec + AES_BLOCK_SIZE);
|
||||
|
||||
while (len)
|
||||
{
|
||||
load_block(tmp, in);
|
||||
tmp2 = tmp;
|
||||
for(n=0 ; n < N_WORDS; ++n)
|
||||
tmp.data[n] ^= iv2.data[n];
|
||||
AES_decrypt((unsigned char *)tmp.data, (unsigned char *)tmp.data, key);
|
||||
for(n=0 ; n < N_WORDS; ++n)
|
||||
tmp.data[n] ^= iv.data[n];
|
||||
store_block(out, tmp);
|
||||
iv = tmp2;
|
||||
iv2 = tmp;
|
||||
--len;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
memcpy(ivec, iv.data, AES_BLOCK_SIZE);
|
||||
memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
while (len) {
|
||||
load_block(tmp, in);
|
||||
tmp2 = tmp;
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
tmp.data[n] ^= iv2.data[n];
|
||||
AES_decrypt((unsigned char *)tmp.data,
|
||||
(unsigned char *)tmp.data, key);
|
||||
for (n = 0; n < N_WORDS; ++n)
|
||||
tmp.data[n] ^= iv.data[n];
|
||||
store_block(out, tmp);
|
||||
iv = tmp2;
|
||||
iv2 = tmp;
|
||||
--len;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
memcpy(ivec, iv.data, AES_BLOCK_SIZE);
|
||||
memcpy(ivec + AES_BLOCK_SIZE, iv2.data, AES_BLOCK_SIZE);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Note that its effectively impossible to do biIGE in anything other
|
||||
@ -211,113 +206,118 @@ void AES_ige_encrypt(const unsigned char *in, unsigned char *out,
|
||||
/* N.B. The IV for this mode is _four times_ the block size */
|
||||
|
||||
void AES_bi_ige_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
const AES_KEY *key2, const unsigned char *ivec,
|
||||
const int enc)
|
||||
{
|
||||
size_t n;
|
||||
size_t len = length;
|
||||
unsigned char tmp[AES_BLOCK_SIZE];
|
||||
unsigned char tmp2[AES_BLOCK_SIZE];
|
||||
unsigned char tmp3[AES_BLOCK_SIZE];
|
||||
unsigned char prev[AES_BLOCK_SIZE];
|
||||
const unsigned char *iv;
|
||||
const unsigned char *iv2;
|
||||
size_t length, const AES_KEY *key,
|
||||
const AES_KEY *key2, const unsigned char *ivec,
|
||||
const int enc)
|
||||
{
|
||||
size_t n;
|
||||
size_t len = length;
|
||||
unsigned char tmp[AES_BLOCK_SIZE];
|
||||
unsigned char tmp2[AES_BLOCK_SIZE];
|
||||
unsigned char tmp3[AES_BLOCK_SIZE];
|
||||
unsigned char prev[AES_BLOCK_SIZE];
|
||||
const unsigned char *iv;
|
||||
const unsigned char *iv2;
|
||||
|
||||
OPENSSL_assert(in && out && key && ivec);
|
||||
OPENSSL_assert((AES_ENCRYPT == enc)||(AES_DECRYPT == enc));
|
||||
OPENSSL_assert((length%AES_BLOCK_SIZE) == 0);
|
||||
OPENSSL_assert(in && out && key && ivec);
|
||||
OPENSSL_assert((AES_ENCRYPT == enc) || (AES_DECRYPT == enc));
|
||||
OPENSSL_assert((length % AES_BLOCK_SIZE) == 0);
|
||||
|
||||
if (AES_ENCRYPT == enc)
|
||||
{
|
||||
/* XXX: Do a separate case for when in != out (strictly should
|
||||
check for overlap, too) */
|
||||
if (AES_ENCRYPT == enc) {
|
||||
/*
|
||||
* XXX: Do a separate case for when in != out (strictly should check
|
||||
* for overlap, too)
|
||||
*/
|
||||
|
||||
/* First the forward pass */
|
||||
iv = ivec;
|
||||
iv2 = ivec + AES_BLOCK_SIZE;
|
||||
while (len >= AES_BLOCK_SIZE)
|
||||
{
|
||||
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
|
||||
out[n] = in[n] ^ iv[n];
|
||||
AES_encrypt(out, out, key);
|
||||
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
|
||||
out[n] ^= iv2[n];
|
||||
iv = out;
|
||||
memcpy(prev, in, AES_BLOCK_SIZE);
|
||||
iv2 = prev;
|
||||
len -= AES_BLOCK_SIZE;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
/* First the forward pass */
|
||||
iv = ivec;
|
||||
iv2 = ivec + AES_BLOCK_SIZE;
|
||||
while (len >= AES_BLOCK_SIZE) {
|
||||
for (n = 0; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] = in[n] ^ iv[n];
|
||||
AES_encrypt(out, out, key);
|
||||
for (n = 0; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] ^= iv2[n];
|
||||
iv = out;
|
||||
memcpy(prev, in, AES_BLOCK_SIZE);
|
||||
iv2 = prev;
|
||||
len -= AES_BLOCK_SIZE;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* And now backwards */
|
||||
iv = ivec + AES_BLOCK_SIZE*2;
|
||||
iv2 = ivec + AES_BLOCK_SIZE*3;
|
||||
len = length;
|
||||
while(len >= AES_BLOCK_SIZE)
|
||||
{
|
||||
out -= AES_BLOCK_SIZE;
|
||||
/* XXX: reduce copies by alternating between buffers */
|
||||
memcpy(tmp, out, AES_BLOCK_SIZE);
|
||||
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
|
||||
out[n] ^= iv[n];
|
||||
/* hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE); */
|
||||
AES_encrypt(out, out, key);
|
||||
/* hexdump(stdout,"enc", out, AES_BLOCK_SIZE); */
|
||||
/* hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE); */
|
||||
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
|
||||
out[n] ^= iv2[n];
|
||||
/* hexdump(stdout,"out", out, AES_BLOCK_SIZE); */
|
||||
iv = out;
|
||||
memcpy(prev, tmp, AES_BLOCK_SIZE);
|
||||
iv2 = prev;
|
||||
len -= AES_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* First backwards */
|
||||
iv = ivec + AES_BLOCK_SIZE*2;
|
||||
iv2 = ivec + AES_BLOCK_SIZE*3;
|
||||
in += length;
|
||||
out += length;
|
||||
while (len >= AES_BLOCK_SIZE)
|
||||
{
|
||||
in -= AES_BLOCK_SIZE;
|
||||
out -= AES_BLOCK_SIZE;
|
||||
memcpy(tmp, in, AES_BLOCK_SIZE);
|
||||
memcpy(tmp2, in, AES_BLOCK_SIZE);
|
||||
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
|
||||
tmp[n] ^= iv2[n];
|
||||
AES_decrypt(tmp, out, key);
|
||||
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
|
||||
out[n] ^= iv[n];
|
||||
memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
|
||||
iv = tmp3;
|
||||
iv2 = out;
|
||||
len -= AES_BLOCK_SIZE;
|
||||
}
|
||||
/* And now backwards */
|
||||
iv = ivec + AES_BLOCK_SIZE * 2;
|
||||
iv2 = ivec + AES_BLOCK_SIZE * 3;
|
||||
len = length;
|
||||
while (len >= AES_BLOCK_SIZE) {
|
||||
out -= AES_BLOCK_SIZE;
|
||||
/*
|
||||
* XXX: reduce copies by alternating between buffers
|
||||
*/
|
||||
memcpy(tmp, out, AES_BLOCK_SIZE);
|
||||
for (n = 0; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] ^= iv[n];
|
||||
/*
|
||||
* hexdump(stdout, "out ^ iv", out, AES_BLOCK_SIZE);
|
||||
*/
|
||||
AES_encrypt(out, out, key);
|
||||
/*
|
||||
* hexdump(stdout,"enc", out, AES_BLOCK_SIZE);
|
||||
*/
|
||||
/*
|
||||
* hexdump(stdout,"iv2", iv2, AES_BLOCK_SIZE);
|
||||
*/
|
||||
for (n = 0; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] ^= iv2[n];
|
||||
/*
|
||||
* hexdump(stdout,"out", out, AES_BLOCK_SIZE);
|
||||
*/
|
||||
iv = out;
|
||||
memcpy(prev, tmp, AES_BLOCK_SIZE);
|
||||
iv2 = prev;
|
||||
len -= AES_BLOCK_SIZE;
|
||||
}
|
||||
} else {
|
||||
/* First backwards */
|
||||
iv = ivec + AES_BLOCK_SIZE * 2;
|
||||
iv2 = ivec + AES_BLOCK_SIZE * 3;
|
||||
in += length;
|
||||
out += length;
|
||||
while (len >= AES_BLOCK_SIZE) {
|
||||
in -= AES_BLOCK_SIZE;
|
||||
out -= AES_BLOCK_SIZE;
|
||||
memcpy(tmp, in, AES_BLOCK_SIZE);
|
||||
memcpy(tmp2, in, AES_BLOCK_SIZE);
|
||||
for (n = 0; n < AES_BLOCK_SIZE; ++n)
|
||||
tmp[n] ^= iv2[n];
|
||||
AES_decrypt(tmp, out, key);
|
||||
for (n = 0; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] ^= iv[n];
|
||||
memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
|
||||
iv = tmp3;
|
||||
iv2 = out;
|
||||
len -= AES_BLOCK_SIZE;
|
||||
}
|
||||
|
||||
/* And now forwards */
|
||||
iv = ivec;
|
||||
iv2 = ivec + AES_BLOCK_SIZE;
|
||||
len = length;
|
||||
while (len >= AES_BLOCK_SIZE)
|
||||
{
|
||||
memcpy(tmp, out, AES_BLOCK_SIZE);
|
||||
memcpy(tmp2, out, AES_BLOCK_SIZE);
|
||||
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
|
||||
tmp[n] ^= iv2[n];
|
||||
AES_decrypt(tmp, out, key);
|
||||
for(n=0 ; n < AES_BLOCK_SIZE ; ++n)
|
||||
out[n] ^= iv[n];
|
||||
memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
|
||||
iv = tmp3;
|
||||
iv2 = out;
|
||||
len -= AES_BLOCK_SIZE;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
/* And now forwards */
|
||||
iv = ivec;
|
||||
iv2 = ivec + AES_BLOCK_SIZE;
|
||||
len = length;
|
||||
while (len >= AES_BLOCK_SIZE) {
|
||||
memcpy(tmp, out, AES_BLOCK_SIZE);
|
||||
memcpy(tmp2, out, AES_BLOCK_SIZE);
|
||||
for (n = 0; n < AES_BLOCK_SIZE; ++n)
|
||||
tmp[n] ^= iv2[n];
|
||||
AES_decrypt(tmp, out, key);
|
||||
for (n = 0; n < AES_BLOCK_SIZE; ++n)
|
||||
out[n] ^= iv[n];
|
||||
memcpy(tmp3, tmp2, AES_BLOCK_SIZE);
|
||||
iv = tmp3;
|
||||
iv2 = out;
|
||||
len -= AES_BLOCK_SIZE;
|
||||
in += AES_BLOCK_SIZE;
|
||||
out += AES_BLOCK_SIZE;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* crypto/aes/aes.h -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* crypto/aes/aes.h */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
@ -7,7 +7,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -50,40 +50,40 @@
|
||||
*/
|
||||
|
||||
#ifndef HEADER_AES_LOCL_H
|
||||
#define HEADER_AES_LOCL_H
|
||||
# define HEADER_AES_LOCL_H
|
||||
|
||||
#include <openssl/e_os2.h>
|
||||
# include <openssl/e_os2.h>
|
||||
|
||||
#ifdef OPENSSL_NO_AES
|
||||
#error AES is disabled.
|
||||
#endif
|
||||
# ifdef OPENSSL_NO_AES
|
||||
# error AES is disabled.
|
||||
# endif
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
# include <stdio.h>
|
||||
# include <stdlib.h>
|
||||
# include <string.h>
|
||||
|
||||
#if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
|
||||
# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
|
||||
# define GETU32(p) SWAP(*((u32 *)(p)))
|
||||
# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
|
||||
#else
|
||||
# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
|
||||
# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
|
||||
#endif
|
||||
# if defined(_MSC_VER) && (defined(_M_IX86) || defined(_M_AMD64) || defined(_M_X64))
|
||||
# define SWAP(x) (_lrotl(x, 8) & 0x00ff00ff | _lrotr(x, 8) & 0xff00ff00)
|
||||
# define GETU32(p) SWAP(*((u32 *)(p)))
|
||||
# define PUTU32(ct, st) { *((u32 *)(ct)) = SWAP((st)); }
|
||||
# else
|
||||
# define GETU32(pt) (((u32)(pt)[0] << 24) ^ ((u32)(pt)[1] << 16) ^ ((u32)(pt)[2] << 8) ^ ((u32)(pt)[3]))
|
||||
# define PUTU32(ct, st) { (ct)[0] = (u8)((st) >> 24); (ct)[1] = (u8)((st) >> 16); (ct)[2] = (u8)((st) >> 8); (ct)[3] = (u8)(st); }
|
||||
# endif
|
||||
|
||||
#ifdef AES_LONG
|
||||
# ifdef AES_LONG
|
||||
typedef unsigned long u32;
|
||||
#else
|
||||
# else
|
||||
typedef unsigned int u32;
|
||||
#endif
|
||||
# endif
|
||||
typedef unsigned short u16;
|
||||
typedef unsigned char u8;
|
||||
|
||||
#define MAXKC (256/32)
|
||||
#define MAXKB (256/8)
|
||||
#define MAXNR 14
|
||||
# define MAXKC (256/32)
|
||||
# define MAXKB (256/8)
|
||||
# define MAXNR 14
|
||||
|
||||
/* This controls loop-unrolling in aes_core.c */
|
||||
#undef FULL_UNROLL
|
||||
# undef FULL_UNROLL
|
||||
|
||||
#endif /* !HEADER_AES_LOCL_H */
|
||||
#endif /* !HEADER_AES_LOCL_H */
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* crypto/aes/aes_misc.c -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* crypto/aes/aes_misc.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1998-2002 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
@ -7,7 +7,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -54,32 +54,33 @@
|
||||
#include <openssl/aes.h>
|
||||
#include "aes_locl.h"
|
||||
|
||||
const char AES_version[]="AES" OPENSSL_VERSION_PTEXT;
|
||||
const char AES_version[] = "AES" OPENSSL_VERSION_PTEXT;
|
||||
|
||||
const char *AES_options(void) {
|
||||
const char *AES_options(void)
|
||||
{
|
||||
#ifdef FULL_UNROLL
|
||||
return "aes(full)";
|
||||
#else
|
||||
return "aes(partial)";
|
||||
return "aes(full)";
|
||||
#else
|
||||
return "aes(partial)";
|
||||
#endif
|
||||
}
|
||||
|
||||
/* FIPS wrapper functions to block low level AES calls in FIPS mode */
|
||||
|
||||
int AES_set_encrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key)
|
||||
{
|
||||
AES_KEY *key)
|
||||
{
|
||||
#ifdef OPENSSL_FIPS
|
||||
fips_cipher_abort(AES);
|
||||
fips_cipher_abort(AES);
|
||||
#endif
|
||||
return private_AES_set_encrypt_key(userKey, bits, key);
|
||||
}
|
||||
return private_AES_set_encrypt_key(userKey, bits, key);
|
||||
}
|
||||
|
||||
int AES_set_decrypt_key(const unsigned char *userKey, const int bits,
|
||||
AES_KEY *key)
|
||||
{
|
||||
AES_KEY *key)
|
||||
{
|
||||
#ifdef OPENSSL_FIPS
|
||||
fips_cipher_abort(AES);
|
||||
fips_cipher_abort(AES);
|
||||
#endif
|
||||
return private_AES_set_decrypt_key(userKey, bits, key);
|
||||
}
|
||||
return private_AES_set_decrypt_key(userKey, bits, key);
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
/* crypto/aes/aes_ofb.c -*- mode:C; c-file-style: "eay" -*- */
|
||||
/* crypto/aes/aes_ofb.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2002-2006 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
@ -7,7 +7,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -53,8 +53,9 @@
|
||||
#include <openssl/modes.h>
|
||||
|
||||
void AES_ofb128_encrypt(const unsigned char *in, unsigned char *out,
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char *ivec, int *num)
|
||||
size_t length, const AES_KEY *key,
|
||||
unsigned char *ivec, int *num)
|
||||
{
|
||||
CRYPTO_ofb128_encrypt(in,out,length,key,ivec,num,(block128_f)AES_encrypt);
|
||||
CRYPTO_ofb128_encrypt(in, out, length, key, ivec, num,
|
||||
(block128_f) AES_encrypt);
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/* crypto/aes/aes_wrap.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -56,204 +57,194 @@
|
||||
#include <openssl/bio.h>
|
||||
|
||||
static const unsigned char default_iv[] = {
|
||||
0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
|
||||
0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6, 0xA6,
|
||||
};
|
||||
|
||||
int AES_wrap_key(AES_KEY *key, const unsigned char *iv,
|
||||
unsigned char *out,
|
||||
const unsigned char *in, unsigned int inlen)
|
||||
{
|
||||
unsigned char *A, B[16], *R;
|
||||
unsigned int i, j, t;
|
||||
if ((inlen & 0x7) || (inlen < 8))
|
||||
return -1;
|
||||
A = B;
|
||||
t = 1;
|
||||
memcpy(out + 8, in, inlen);
|
||||
if (!iv)
|
||||
iv = default_iv;
|
||||
unsigned char *out,
|
||||
const unsigned char *in, unsigned int inlen)
|
||||
{
|
||||
unsigned char *A, B[16], *R;
|
||||
unsigned int i, j, t;
|
||||
if ((inlen & 0x7) || (inlen < 8))
|
||||
return -1;
|
||||
A = B;
|
||||
t = 1;
|
||||
memcpy(out + 8, in, inlen);
|
||||
if (!iv)
|
||||
iv = default_iv;
|
||||
|
||||
memcpy(A, iv, 8);
|
||||
memcpy(A, iv, 8);
|
||||
|
||||
for (j = 0; j < 6; j++)
|
||||
{
|
||||
R = out + 8;
|
||||
for (i = 0; i < inlen; i += 8, t++, R += 8)
|
||||
{
|
||||
memcpy(B + 8, R, 8);
|
||||
AES_encrypt(B, B, key);
|
||||
A[7] ^= (unsigned char)(t & 0xff);
|
||||
if (t > 0xff)
|
||||
{
|
||||
A[6] ^= (unsigned char)((t >> 8) & 0xff);
|
||||
A[5] ^= (unsigned char)((t >> 16) & 0xff);
|
||||
A[4] ^= (unsigned char)((t >> 24) & 0xff);
|
||||
}
|
||||
memcpy(R, B + 8, 8);
|
||||
}
|
||||
}
|
||||
memcpy(out, A, 8);
|
||||
return inlen + 8;
|
||||
}
|
||||
for (j = 0; j < 6; j++) {
|
||||
R = out + 8;
|
||||
for (i = 0; i < inlen; i += 8, t++, R += 8) {
|
||||
memcpy(B + 8, R, 8);
|
||||
AES_encrypt(B, B, key);
|
||||
A[7] ^= (unsigned char)(t & 0xff);
|
||||
if (t > 0xff) {
|
||||
A[6] ^= (unsigned char)((t >> 8) & 0xff);
|
||||
A[5] ^= (unsigned char)((t >> 16) & 0xff);
|
||||
A[4] ^= (unsigned char)((t >> 24) & 0xff);
|
||||
}
|
||||
memcpy(R, B + 8, 8);
|
||||
}
|
||||
}
|
||||
memcpy(out, A, 8);
|
||||
return inlen + 8;
|
||||
}
|
||||
|
||||
int AES_unwrap_key(AES_KEY *key, const unsigned char *iv,
|
||||
unsigned char *out,
|
||||
const unsigned char *in, unsigned int inlen)
|
||||
{
|
||||
unsigned char *A, B[16], *R;
|
||||
unsigned int i, j, t;
|
||||
inlen -= 8;
|
||||
if (inlen & 0x7)
|
||||
return -1;
|
||||
if (inlen < 8)
|
||||
return -1;
|
||||
A = B;
|
||||
t = 6 * (inlen >> 3);
|
||||
memcpy(A, in, 8);
|
||||
memcpy(out, in + 8, inlen);
|
||||
for (j = 0; j < 6; j++)
|
||||
{
|
||||
R = out + inlen - 8;
|
||||
for (i = 0; i < inlen; i += 8, t--, R -= 8)
|
||||
{
|
||||
A[7] ^= (unsigned char)(t & 0xff);
|
||||
if (t > 0xff)
|
||||
{
|
||||
A[6] ^= (unsigned char)((t >> 8) & 0xff);
|
||||
A[5] ^= (unsigned char)((t >> 16) & 0xff);
|
||||
A[4] ^= (unsigned char)((t >> 24) & 0xff);
|
||||
}
|
||||
memcpy(B + 8, R, 8);
|
||||
AES_decrypt(B, B, key);
|
||||
memcpy(R, B + 8, 8);
|
||||
}
|
||||
}
|
||||
if (!iv)
|
||||
iv = default_iv;
|
||||
if (memcmp(A, iv, 8))
|
||||
{
|
||||
OPENSSL_cleanse(out, inlen);
|
||||
return 0;
|
||||
}
|
||||
return inlen;
|
||||
}
|
||||
unsigned char *out,
|
||||
const unsigned char *in, unsigned int inlen)
|
||||
{
|
||||
unsigned char *A, B[16], *R;
|
||||
unsigned int i, j, t;
|
||||
inlen -= 8;
|
||||
if (inlen & 0x7)
|
||||
return -1;
|
||||
if (inlen < 8)
|
||||
return -1;
|
||||
A = B;
|
||||
t = 6 * (inlen >> 3);
|
||||
memcpy(A, in, 8);
|
||||
memcpy(out, in + 8, inlen);
|
||||
for (j = 0; j < 6; j++) {
|
||||
R = out + inlen - 8;
|
||||
for (i = 0; i < inlen; i += 8, t--, R -= 8) {
|
||||
A[7] ^= (unsigned char)(t & 0xff);
|
||||
if (t > 0xff) {
|
||||
A[6] ^= (unsigned char)((t >> 8) & 0xff);
|
||||
A[5] ^= (unsigned char)((t >> 16) & 0xff);
|
||||
A[4] ^= (unsigned char)((t >> 24) & 0xff);
|
||||
}
|
||||
memcpy(B + 8, R, 8);
|
||||
AES_decrypt(B, B, key);
|
||||
memcpy(R, B + 8, 8);
|
||||
}
|
||||
}
|
||||
if (!iv)
|
||||
iv = default_iv;
|
||||
if (memcmp(A, iv, 8)) {
|
||||
OPENSSL_cleanse(out, inlen);
|
||||
return 0;
|
||||
}
|
||||
return inlen;
|
||||
}
|
||||
|
||||
#ifdef AES_WRAP_TEST
|
||||
|
||||
int AES_wrap_unwrap_test(const unsigned char *kek, int keybits,
|
||||
const unsigned char *iv,
|
||||
const unsigned char *eout,
|
||||
const unsigned char *key, int keylen)
|
||||
{
|
||||
unsigned char *otmp = NULL, *ptmp = NULL;
|
||||
int r, ret = 0;
|
||||
AES_KEY wctx;
|
||||
otmp = OPENSSL_malloc(keylen + 8);
|
||||
ptmp = OPENSSL_malloc(keylen);
|
||||
if (!otmp || !ptmp)
|
||||
return 0;
|
||||
if (AES_set_encrypt_key(kek, keybits, &wctx))
|
||||
goto err;
|
||||
r = AES_wrap_key(&wctx, iv, otmp, key, keylen);
|
||||
if (r <= 0)
|
||||
goto err;
|
||||
const unsigned char *iv,
|
||||
const unsigned char *eout,
|
||||
const unsigned char *key, int keylen)
|
||||
{
|
||||
unsigned char *otmp = NULL, *ptmp = NULL;
|
||||
int r, ret = 0;
|
||||
AES_KEY wctx;
|
||||
otmp = OPENSSL_malloc(keylen + 8);
|
||||
ptmp = OPENSSL_malloc(keylen);
|
||||
if (!otmp || !ptmp)
|
||||
return 0;
|
||||
if (AES_set_encrypt_key(kek, keybits, &wctx))
|
||||
goto err;
|
||||
r = AES_wrap_key(&wctx, iv, otmp, key, keylen);
|
||||
if (r <= 0)
|
||||
goto err;
|
||||
|
||||
if (eout && memcmp(eout, otmp, keylen))
|
||||
goto err;
|
||||
|
||||
if (AES_set_decrypt_key(kek, keybits, &wctx))
|
||||
goto err;
|
||||
r = AES_unwrap_key(&wctx, iv, ptmp, otmp, r);
|
||||
if (eout && memcmp(eout, otmp, keylen))
|
||||
goto err;
|
||||
|
||||
if (memcmp(key, ptmp, keylen))
|
||||
goto err;
|
||||
if (AES_set_decrypt_key(kek, keybits, &wctx))
|
||||
goto err;
|
||||
r = AES_unwrap_key(&wctx, iv, ptmp, otmp, r);
|
||||
|
||||
ret = 1;
|
||||
if (memcmp(key, ptmp, keylen))
|
||||
goto err;
|
||||
|
||||
err:
|
||||
if (otmp)
|
||||
OPENSSL_free(otmp);
|
||||
if (ptmp)
|
||||
OPENSSL_free(ptmp);
|
||||
ret = 1;
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
err:
|
||||
if (otmp)
|
||||
OPENSSL_free(otmp);
|
||||
if (ptmp)
|
||||
OPENSSL_free(ptmp);
|
||||
|
||||
return ret;
|
||||
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
|
||||
static const unsigned char kek[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
||||
};
|
||||
static const unsigned char kek[] = {
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f,
|
||||
0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17,
|
||||
0x18, 0x19, 0x1a, 0x1b, 0x1c, 0x1d, 0x1e, 0x1f
|
||||
};
|
||||
|
||||
static const unsigned char key[] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||||
};
|
||||
static const unsigned char key[] = {
|
||||
0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77,
|
||||
0x88, 0x99, 0xaa, 0xbb, 0xcc, 0xdd, 0xee, 0xff,
|
||||
0x00, 0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07,
|
||||
0x08, 0x09, 0x0a, 0x0b, 0x0c, 0x0d, 0x0e, 0x0f
|
||||
};
|
||||
|
||||
static const unsigned char e1[] = {
|
||||
0x1f, 0xa6, 0x8b, 0x0a, 0x81, 0x12, 0xb4, 0x47,
|
||||
0xae, 0xf3, 0x4b, 0xd8, 0xfb, 0x5a, 0x7b, 0x82,
|
||||
0x9d, 0x3e, 0x86, 0x23, 0x71, 0xd2, 0xcf, 0xe5
|
||||
};
|
||||
static const unsigned char e1[] = {
|
||||
0x1f, 0xa6, 0x8b, 0x0a, 0x81, 0x12, 0xb4, 0x47,
|
||||
0xae, 0xf3, 0x4b, 0xd8, 0xfb, 0x5a, 0x7b, 0x82,
|
||||
0x9d, 0x3e, 0x86, 0x23, 0x71, 0xd2, 0xcf, 0xe5
|
||||
};
|
||||
|
||||
static const unsigned char e2[] = {
|
||||
0x96, 0x77, 0x8b, 0x25, 0xae, 0x6c, 0xa4, 0x35,
|
||||
0xf9, 0x2b, 0x5b, 0x97, 0xc0, 0x50, 0xae, 0xd2,
|
||||
0x46, 0x8a, 0xb8, 0xa1, 0x7a, 0xd8, 0x4e, 0x5d
|
||||
};
|
||||
static const unsigned char e2[] = {
|
||||
0x96, 0x77, 0x8b, 0x25, 0xae, 0x6c, 0xa4, 0x35,
|
||||
0xf9, 0x2b, 0x5b, 0x97, 0xc0, 0x50, 0xae, 0xd2,
|
||||
0x46, 0x8a, 0xb8, 0xa1, 0x7a, 0xd8, 0x4e, 0x5d
|
||||
};
|
||||
|
||||
static const unsigned char e3[] = {
|
||||
0x64, 0xe8, 0xc3, 0xf9, 0xce, 0x0f, 0x5b, 0xa2,
|
||||
0x63, 0xe9, 0x77, 0x79, 0x05, 0x81, 0x8a, 0x2a,
|
||||
0x93, 0xc8, 0x19, 0x1e, 0x7d, 0x6e, 0x8a, 0xe7
|
||||
};
|
||||
static const unsigned char e3[] = {
|
||||
0x64, 0xe8, 0xc3, 0xf9, 0xce, 0x0f, 0x5b, 0xa2,
|
||||
0x63, 0xe9, 0x77, 0x79, 0x05, 0x81, 0x8a, 0x2a,
|
||||
0x93, 0xc8, 0x19, 0x1e, 0x7d, 0x6e, 0x8a, 0xe7
|
||||
};
|
||||
|
||||
static const unsigned char e4[] = {
|
||||
0x03, 0x1d, 0x33, 0x26, 0x4e, 0x15, 0xd3, 0x32,
|
||||
0x68, 0xf2, 0x4e, 0xc2, 0x60, 0x74, 0x3e, 0xdc,
|
||||
0xe1, 0xc6, 0xc7, 0xdd, 0xee, 0x72, 0x5a, 0x93,
|
||||
0x6b, 0xa8, 0x14, 0x91, 0x5c, 0x67, 0x62, 0xd2
|
||||
};
|
||||
static const unsigned char e4[] = {
|
||||
0x03, 0x1d, 0x33, 0x26, 0x4e, 0x15, 0xd3, 0x32,
|
||||
0x68, 0xf2, 0x4e, 0xc2, 0x60, 0x74, 0x3e, 0xdc,
|
||||
0xe1, 0xc6, 0xc7, 0xdd, 0xee, 0x72, 0x5a, 0x93,
|
||||
0x6b, 0xa8, 0x14, 0x91, 0x5c, 0x67, 0x62, 0xd2
|
||||
};
|
||||
|
||||
static const unsigned char e5[] = {
|
||||
0xa8, 0xf9, 0xbc, 0x16, 0x12, 0xc6, 0x8b, 0x3f,
|
||||
0xf6, 0xe6, 0xf4, 0xfb, 0xe3, 0x0e, 0x71, 0xe4,
|
||||
0x76, 0x9c, 0x8b, 0x80, 0xa3, 0x2c, 0xb8, 0x95,
|
||||
0x8c, 0xd5, 0xd1, 0x7d, 0x6b, 0x25, 0x4d, 0xa1
|
||||
};
|
||||
static const unsigned char e5[] = {
|
||||
0xa8, 0xf9, 0xbc, 0x16, 0x12, 0xc6, 0x8b, 0x3f,
|
||||
0xf6, 0xe6, 0xf4, 0xfb, 0xe3, 0x0e, 0x71, 0xe4,
|
||||
0x76, 0x9c, 0x8b, 0x80, 0xa3, 0x2c, 0xb8, 0x95,
|
||||
0x8c, 0xd5, 0xd1, 0x7d, 0x6b, 0x25, 0x4d, 0xa1
|
||||
};
|
||||
|
||||
static const unsigned char e6[] = {
|
||||
0x28, 0xc9, 0xf4, 0x04, 0xc4, 0xb8, 0x10, 0xf4,
|
||||
0xcb, 0xcc, 0xb3, 0x5c, 0xfb, 0x87, 0xf8, 0x26,
|
||||
0x3f, 0x57, 0x86, 0xe2, 0xd8, 0x0e, 0xd3, 0x26,
|
||||
0xcb, 0xc7, 0xf0, 0xe7, 0x1a, 0x99, 0xf4, 0x3b,
|
||||
0xfb, 0x98, 0x8b, 0x9b, 0x7a, 0x02, 0xdd, 0x21
|
||||
};
|
||||
static const unsigned char e6[] = {
|
||||
0x28, 0xc9, 0xf4, 0x04, 0xc4, 0xb8, 0x10, 0xf4,
|
||||
0xcb, 0xcc, 0xb3, 0x5c, 0xfb, 0x87, 0xf8, 0x26,
|
||||
0x3f, 0x57, 0x86, 0xe2, 0xd8, 0x0e, 0xd3, 0x26,
|
||||
0xcb, 0xc7, 0xf0, 0xe7, 0x1a, 0x99, 0xf4, 0x3b,
|
||||
0xfb, 0x98, 0x8b, 0x9b, 0x7a, 0x02, 0xdd, 0x21
|
||||
};
|
||||
|
||||
AES_KEY wctx, xctx;
|
||||
int ret;
|
||||
ret = AES_wrap_unwrap_test(kek, 128, NULL, e1, key, 16);
|
||||
fprintf(stderr, "Key test result %d\n", ret);
|
||||
ret = AES_wrap_unwrap_test(kek, 192, NULL, e2, key, 16);
|
||||
fprintf(stderr, "Key test result %d\n", ret);
|
||||
ret = AES_wrap_unwrap_test(kek, 256, NULL, e3, key, 16);
|
||||
fprintf(stderr, "Key test result %d\n", ret);
|
||||
ret = AES_wrap_unwrap_test(kek, 192, NULL, e4, key, 24);
|
||||
fprintf(stderr, "Key test result %d\n", ret);
|
||||
ret = AES_wrap_unwrap_test(kek, 256, NULL, e5, key, 24);
|
||||
fprintf(stderr, "Key test result %d\n", ret);
|
||||
ret = AES_wrap_unwrap_test(kek, 256, NULL, e6, key, 32);
|
||||
fprintf(stderr, "Key test result %d\n", ret);
|
||||
AES_KEY wctx, xctx;
|
||||
int ret;
|
||||
ret = AES_wrap_unwrap_test(kek, 128, NULL, e1, key, 16);
|
||||
fprintf(stderr, "Key test result %d\n", ret);
|
||||
ret = AES_wrap_unwrap_test(kek, 192, NULL, e2, key, 16);
|
||||
fprintf(stderr, "Key test result %d\n", ret);
|
||||
ret = AES_wrap_unwrap_test(kek, 256, NULL, e3, key, 16);
|
||||
fprintf(stderr, "Key test result %d\n", ret);
|
||||
ret = AES_wrap_unwrap_test(kek, 192, NULL, e4, key, 24);
|
||||
fprintf(stderr, "Key test result %d\n", ret);
|
||||
ret = AES_wrap_unwrap_test(kek, 256, NULL, e5, key, 24);
|
||||
fprintf(stderr, "Key test result %d\n", ret);
|
||||
ret = AES_wrap_unwrap_test(kek, 256, NULL, e6, key, 32);
|
||||
fprintf(stderr, "Key test result %d\n", ret);
|
||||
}
|
||||
|
||||
|
||||
|
||||
#endif
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -45,7 +45,7 @@
|
||||
# the undertaken effort was that it appeared that in tight IA-32
|
||||
# register window little-endian flavor could achieve slightly higher
|
||||
# Instruction Level Parallelism, and it indeed resulted in up to 15%
|
||||
# better performance on most recent <EFBFBD>-archs...
|
||||
# better performance on most recent µ-archs...
|
||||
#
|
||||
# Third version adds AES_cbc_encrypt implementation, which resulted in
|
||||
# up to 40% performance imrovement of CBC benchmark results. 40% was
|
||||
@ -223,7 +223,7 @@ sub _data_word() { my $i; while(defined($i=shift)) { &data_word($i,$i); } }
|
||||
$speed_limit=512; # chunks smaller than $speed_limit are
|
||||
# processed with compact routine in CBC mode
|
||||
$small_footprint=1; # $small_footprint=1 code is ~5% slower [on
|
||||
# recent <EFBFBD>-archs], but ~5 times smaller!
|
||||
# recent µ-archs], but ~5 times smaller!
|
||||
# I favor compact code to minimize cache
|
||||
# contention and in hope to "collect" 5% back
|
||||
# in real-life applications...
|
||||
@ -562,7 +562,7 @@ sub enctransform()
|
||||
# Performance is not actually extraordinary in comparison to pure
|
||||
# x86 code. In particular encrypt performance is virtually the same.
|
||||
# Decrypt performance on the other hand is 15-20% better on newer
|
||||
# <EFBFBD>-archs [but we're thankful for *any* improvement here], and ~50%
|
||||
# µ-archs [but we're thankful for *any* improvement here], and ~50%
|
||||
# better on PIII:-) And additionally on the pros side this code
|
||||
# eliminates redundant references to stack and thus relieves/
|
||||
# minimizes the pressure on the memory bus.
|
||||
|
||||
@ -70,7 +70,7 @@ $pf = ($flavour =~ /nubi/i) ? $t0 : $t2;
|
||||
#
|
||||
######################################################################
|
||||
|
||||
$big_endian=(`echo MIPSEL | $ENV{CC} -E -P -`=~/MIPSEL/)?1:0;
|
||||
$big_endian=(`echo MIPSEL | $ENV{CC} -E -`=~/MIPSEL/)?1:0 if ($ENV{CC});
|
||||
|
||||
for (@ARGV) { $output=$_ if (/^\w[\w\-]*\.\w+$/); }
|
||||
open STDOUT,">$output";
|
||||
|
||||
@ -74,7 +74,7 @@ $inout3="xmm5"; $in1="xmm5";
|
||||
$inout4="xmm6"; $in0="xmm6";
|
||||
$inout5="xmm7"; $ivec="xmm7";
|
||||
|
||||
# AESNI extenstion
|
||||
# AESNI extension
|
||||
sub aeskeygenassist
|
||||
{ my($dst,$src,$imm)=@_;
|
||||
if ("$dst:$src" =~ /xmm([0-7]):xmm([0-7])/)
|
||||
|
||||
@ -525,6 +525,16 @@ $code.=<<___;
|
||||
.type aesni_ecb_encrypt,\@function,5
|
||||
.align 16
|
||||
aesni_ecb_encrypt:
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
lea -0x58(%rsp),%rsp
|
||||
movaps %xmm6,(%rsp)
|
||||
movaps %xmm7,0x10(%rsp)
|
||||
movaps %xmm8,0x20(%rsp)
|
||||
movaps %xmm9,0x30(%rsp)
|
||||
.Lecb_enc_body:
|
||||
___
|
||||
$code.=<<___;
|
||||
and \$-16,$len
|
||||
jz .Lecb_ret
|
||||
|
||||
@ -805,6 +815,16 @@ $code.=<<___;
|
||||
movups $inout5,0x50($out)
|
||||
|
||||
.Lecb_ret:
|
||||
___
|
||||
$code.=<<___ if ($win64);
|
||||
movaps (%rsp),%xmm6
|
||||
movaps 0x10(%rsp),%xmm7
|
||||
movaps 0x20(%rsp),%xmm8
|
||||
movaps 0x30(%rsp),%xmm9
|
||||
lea 0x58(%rsp),%rsp
|
||||
.Lecb_enc_ret:
|
||||
___
|
||||
$code.=<<___;
|
||||
ret
|
||||
.size aesni_ecb_encrypt,.-aesni_ecb_encrypt
|
||||
___
|
||||
@ -2730,28 +2750,9 @@ $code.=<<___;
|
||||
.extern __imp_RtlVirtualUnwind
|
||||
___
|
||||
$code.=<<___ if ($PREFIX eq "aesni");
|
||||
.type ecb_se_handler,\@abi-omnipotent
|
||||
.type ecb_ccm64_se_handler,\@abi-omnipotent
|
||||
.align 16
|
||||
ecb_se_handler:
|
||||
push %rsi
|
||||
push %rdi
|
||||
push %rbx
|
||||
push %rbp
|
||||
push %r12
|
||||
push %r13
|
||||
push %r14
|
||||
push %r15
|
||||
pushfq
|
||||
sub \$64,%rsp
|
||||
|
||||
mov 152($context),%rax # pull context->Rsp
|
||||
|
||||
jmp .Lcommon_seh_tail
|
||||
.size ecb_se_handler,.-ecb_se_handler
|
||||
|
||||
.type ccm64_se_handler,\@abi-omnipotent
|
||||
.align 16
|
||||
ccm64_se_handler:
|
||||
ecb_ccm64_se_handler:
|
||||
push %rsi
|
||||
push %rdi
|
||||
push %rbx
|
||||
@ -2788,7 +2789,7 @@ ccm64_se_handler:
|
||||
lea 0x58(%rax),%rax # adjust stack pointer
|
||||
|
||||
jmp .Lcommon_seh_tail
|
||||
.size ccm64_se_handler,.-ccm64_se_handler
|
||||
.size ecb_ccm64_se_handler,.-ecb_ccm64_se_handler
|
||||
|
||||
.type ctr32_se_handler,\@abi-omnipotent
|
||||
.align 16
|
||||
@ -2993,14 +2994,15 @@ ___
|
||||
$code.=<<___ if ($PREFIX eq "aesni");
|
||||
.LSEH_info_ecb:
|
||||
.byte 9,0,0,0
|
||||
.rva ecb_se_handler
|
||||
.rva ecb_ccm64_se_handler
|
||||
.rva .Lecb_enc_body,.Lecb_enc_ret # HandlerData[]
|
||||
.LSEH_info_ccm64_enc:
|
||||
.byte 9,0,0,0
|
||||
.rva ccm64_se_handler
|
||||
.rva ecb_ccm64_se_handler
|
||||
.rva .Lccm64_enc_body,.Lccm64_enc_ret # HandlerData[]
|
||||
.LSEH_info_ccm64_dec:
|
||||
.byte 9,0,0,0
|
||||
.rva ccm64_se_handler
|
||||
.rva ecb_ccm64_se_handler
|
||||
.rva .Lccm64_dec_body,.Lccm64_dec_ret # HandlerData[]
|
||||
.LSEH_info_ctr32:
|
||||
.byte 9,0,0,0
|
||||
|
||||
@ -1,51 +1,51 @@
|
||||
#ifndef __ARM_ARCH_H__
|
||||
#define __ARM_ARCH_H__
|
||||
# define __ARM_ARCH_H__
|
||||
|
||||
#if !defined(__ARM_ARCH__)
|
||||
# if defined(__CC_ARM)
|
||||
# define __ARM_ARCH__ __TARGET_ARCH_ARM
|
||||
# if defined(__BIG_ENDIAN)
|
||||
# define __ARMEB__
|
||||
# else
|
||||
# define __ARMEL__
|
||||
# endif
|
||||
# elif defined(__GNUC__)
|
||||
# if !defined(__ARM_ARCH__)
|
||||
# if defined(__CC_ARM)
|
||||
# define __ARM_ARCH__ __TARGET_ARCH_ARM
|
||||
# if defined(__BIG_ENDIAN)
|
||||
# define __ARMEB__
|
||||
# else
|
||||
# define __ARMEL__
|
||||
# endif
|
||||
# elif defined(__GNUC__)
|
||||
/*
|
||||
* Why doesn't gcc define __ARM_ARCH__? Instead it defines
|
||||
* bunch of below macros. See all_architectires[] table in
|
||||
* gcc/config/arm/arm.c. On a side note it defines
|
||||
* __ARMEL__/__ARMEB__ for little-/big-endian.
|
||||
*/
|
||||
# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
|
||||
defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \
|
||||
defined(__ARM_ARCH_7EM__)
|
||||
# define __ARM_ARCH__ 7
|
||||
# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
|
||||
defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__) || \
|
||||
defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__) || \
|
||||
defined(__ARM_ARCH_6T2__)
|
||||
# define __ARM_ARCH__ 6
|
||||
# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \
|
||||
defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__) || \
|
||||
defined(__ARM_ARCH_5TEJ__)
|
||||
# define __ARM_ARCH__ 5
|
||||
# elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
|
||||
# define __ARM_ARCH__ 4
|
||||
# else
|
||||
# error "unsupported ARM architecture"
|
||||
# if defined(__ARM_ARCH_7__) || defined(__ARM_ARCH_7A__) || \
|
||||
defined(__ARM_ARCH_7R__)|| defined(__ARM_ARCH_7M__) || \
|
||||
defined(__ARM_ARCH_7EM__)
|
||||
# define __ARM_ARCH__ 7
|
||||
# elif defined(__ARM_ARCH_6__) || defined(__ARM_ARCH_6J__) || \
|
||||
defined(__ARM_ARCH_6K__)|| defined(__ARM_ARCH_6M__) || \
|
||||
defined(__ARM_ARCH_6Z__)|| defined(__ARM_ARCH_6ZK__) || \
|
||||
defined(__ARM_ARCH_6T2__)
|
||||
# define __ARM_ARCH__ 6
|
||||
# elif defined(__ARM_ARCH_5__) || defined(__ARM_ARCH_5T__) || \
|
||||
defined(__ARM_ARCH_5E__)|| defined(__ARM_ARCH_5TE__) || \
|
||||
defined(__ARM_ARCH_5TEJ__)
|
||||
# define __ARM_ARCH__ 5
|
||||
# elif defined(__ARM_ARCH_4__) || defined(__ARM_ARCH_4T__)
|
||||
# define __ARM_ARCH__ 4
|
||||
# else
|
||||
# error "unsupported ARM architecture"
|
||||
# endif
|
||||
# endif
|
||||
# endif
|
||||
#endif
|
||||
|
||||
#ifdef OPENSSL_FIPSCANISTER
|
||||
#include <openssl/fipssyms.h>
|
||||
#endif
|
||||
# ifdef OPENSSL_FIPSCANISTER
|
||||
# include <openssl/fipssyms.h>
|
||||
# endif
|
||||
|
||||
#if !__ASSEMBLER__
|
||||
# if !__ASSEMBLER__
|
||||
extern unsigned int OPENSSL_armcap_P;
|
||||
|
||||
#define ARMV7_NEON (1<<0)
|
||||
#define ARMV7_TICK (1<<1)
|
||||
#endif
|
||||
|
||||
# define ARMV7_NEON (1<<0)
|
||||
# define ARMV7_TICK (1<<1)
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -12,7 +12,10 @@ unsigned int OPENSSL_armcap_P;
|
||||
static sigset_t all_masked;
|
||||
|
||||
static sigjmp_buf ill_jmp;
|
||||
static void ill_handler (int sig) { siglongjmp(ill_jmp,sig); }
|
||||
static void ill_handler(int sig)
|
||||
{
|
||||
siglongjmp(ill_jmp, sig);
|
||||
}
|
||||
|
||||
/*
|
||||
* Following subroutines could have been inlined, but it's not all
|
||||
@ -22,59 +25,57 @@ void _armv7_neon_probe(void);
|
||||
unsigned int _armv7_tick(void);
|
||||
|
||||
unsigned int OPENSSL_rdtsc(void)
|
||||
{
|
||||
if (OPENSSL_armcap_P & ARMV7_TICK)
|
||||
return _armv7_tick();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
if (OPENSSL_armcap_P & ARMV7_TICK)
|
||||
return _armv7_tick();
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if defined(__GNUC__) && __GNUC__>=2
|
||||
void OPENSSL_cpuid_setup(void) __attribute__((constructor));
|
||||
void OPENSSL_cpuid_setup(void) __attribute__ ((constructor));
|
||||
#endif
|
||||
void OPENSSL_cpuid_setup(void)
|
||||
{
|
||||
char *e;
|
||||
struct sigaction ill_oact,ill_act;
|
||||
sigset_t oset;
|
||||
static int trigger=0;
|
||||
{
|
||||
char *e;
|
||||
struct sigaction ill_oact, ill_act;
|
||||
sigset_t oset;
|
||||
static int trigger = 0;
|
||||
|
||||
if (trigger) return;
|
||||
trigger=1;
|
||||
|
||||
if ((e=getenv("OPENSSL_armcap")))
|
||||
{
|
||||
OPENSSL_armcap_P=strtoul(e,NULL,0);
|
||||
return;
|
||||
}
|
||||
if (trigger)
|
||||
return;
|
||||
trigger = 1;
|
||||
|
||||
sigfillset(&all_masked);
|
||||
sigdelset(&all_masked,SIGILL);
|
||||
sigdelset(&all_masked,SIGTRAP);
|
||||
sigdelset(&all_masked,SIGFPE);
|
||||
sigdelset(&all_masked,SIGBUS);
|
||||
sigdelset(&all_masked,SIGSEGV);
|
||||
if ((e = getenv("OPENSSL_armcap"))) {
|
||||
OPENSSL_armcap_P = strtoul(e, NULL, 0);
|
||||
return;
|
||||
}
|
||||
|
||||
OPENSSL_armcap_P = 0;
|
||||
sigfillset(&all_masked);
|
||||
sigdelset(&all_masked, SIGILL);
|
||||
sigdelset(&all_masked, SIGTRAP);
|
||||
sigdelset(&all_masked, SIGFPE);
|
||||
sigdelset(&all_masked, SIGBUS);
|
||||
sigdelset(&all_masked, SIGSEGV);
|
||||
|
||||
memset(&ill_act,0,sizeof(ill_act));
|
||||
ill_act.sa_handler = ill_handler;
|
||||
ill_act.sa_mask = all_masked;
|
||||
OPENSSL_armcap_P = 0;
|
||||
|
||||
sigprocmask(SIG_SETMASK,&ill_act.sa_mask,&oset);
|
||||
sigaction(SIGILL,&ill_act,&ill_oact);
|
||||
memset(&ill_act, 0, sizeof(ill_act));
|
||||
ill_act.sa_handler = ill_handler;
|
||||
ill_act.sa_mask = all_masked;
|
||||
|
||||
if (sigsetjmp(ill_jmp,1) == 0)
|
||||
{
|
||||
_armv7_neon_probe();
|
||||
OPENSSL_armcap_P |= ARMV7_NEON;
|
||||
}
|
||||
if (sigsetjmp(ill_jmp,1) == 0)
|
||||
{
|
||||
_armv7_tick();
|
||||
OPENSSL_armcap_P |= ARMV7_TICK;
|
||||
}
|
||||
sigprocmask(SIG_SETMASK, &ill_act.sa_mask, &oset);
|
||||
sigaction(SIGILL, &ill_act, &ill_oact);
|
||||
|
||||
sigaction (SIGILL,&ill_oact,NULL);
|
||||
sigprocmask(SIG_SETMASK,&oset,NULL);
|
||||
}
|
||||
if (sigsetjmp(ill_jmp, 1) == 0) {
|
||||
_armv7_neon_probe();
|
||||
OPENSSL_armcap_P |= ARMV7_NEON;
|
||||
}
|
||||
if (sigsetjmp(ill_jmp, 1) == 0) {
|
||||
_armv7_tick();
|
||||
OPENSSL_armcap_P |= ARMV7_TICK;
|
||||
}
|
||||
|
||||
sigaction(SIGILL, &ill_oact, NULL);
|
||||
sigprocmask(SIG_SETMASK, &oset, NULL);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -61,188 +61,202 @@
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
int ASN1_BIT_STRING_set(ASN1_BIT_STRING *x, unsigned char *d, int len)
|
||||
{ return M_ASN1_BIT_STRING_set(x, d, len); }
|
||||
{
|
||||
return M_ASN1_BIT_STRING_set(x, d, len);
|
||||
}
|
||||
|
||||
int i2c_ASN1_BIT_STRING(ASN1_BIT_STRING *a, unsigned char **pp)
|
||||
{
|
||||
int ret,j,bits,len;
|
||||
unsigned char *p,*d;
|
||||
{
|
||||
int ret, j, bits, len;
|
||||
unsigned char *p, *d;
|
||||
|
||||
if (a == NULL) return(0);
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
|
||||
len=a->length;
|
||||
len = a->length;
|
||||
|
||||
if (len > 0)
|
||||
{
|
||||
if (a->flags & ASN1_STRING_FLAG_BITS_LEFT)
|
||||
{
|
||||
bits=(int)a->flags&0x07;
|
||||
}
|
||||
else
|
||||
{
|
||||
for ( ; len > 0; len--)
|
||||
{
|
||||
if (a->data[len-1]) break;
|
||||
}
|
||||
j=a->data[len-1];
|
||||
if (j & 0x01) bits=0;
|
||||
else if (j & 0x02) bits=1;
|
||||
else if (j & 0x04) bits=2;
|
||||
else if (j & 0x08) bits=3;
|
||||
else if (j & 0x10) bits=4;
|
||||
else if (j & 0x20) bits=5;
|
||||
else if (j & 0x40) bits=6;
|
||||
else if (j & 0x80) bits=7;
|
||||
else bits=0; /* should not happen */
|
||||
}
|
||||
}
|
||||
else
|
||||
bits=0;
|
||||
if (len > 0) {
|
||||
if (a->flags & ASN1_STRING_FLAG_BITS_LEFT) {
|
||||
bits = (int)a->flags & 0x07;
|
||||
} else {
|
||||
for (; len > 0; len--) {
|
||||
if (a->data[len - 1])
|
||||
break;
|
||||
}
|
||||
j = a->data[len - 1];
|
||||
if (j & 0x01)
|
||||
bits = 0;
|
||||
else if (j & 0x02)
|
||||
bits = 1;
|
||||
else if (j & 0x04)
|
||||
bits = 2;
|
||||
else if (j & 0x08)
|
||||
bits = 3;
|
||||
else if (j & 0x10)
|
||||
bits = 4;
|
||||
else if (j & 0x20)
|
||||
bits = 5;
|
||||
else if (j & 0x40)
|
||||
bits = 6;
|
||||
else if (j & 0x80)
|
||||
bits = 7;
|
||||
else
|
||||
bits = 0; /* should not happen */
|
||||
}
|
||||
} else
|
||||
bits = 0;
|
||||
|
||||
ret=1+len;
|
||||
if (pp == NULL) return(ret);
|
||||
ret = 1 + len;
|
||||
if (pp == NULL)
|
||||
return (ret);
|
||||
|
||||
p= *pp;
|
||||
p = *pp;
|
||||
|
||||
*(p++)=(unsigned char)bits;
|
||||
d=a->data;
|
||||
memcpy(p,d,len);
|
||||
p+=len;
|
||||
if (len > 0) p[-1]&=(0xff<<bits);
|
||||
*pp=p;
|
||||
return(ret);
|
||||
}
|
||||
*(p++) = (unsigned char)bits;
|
||||
d = a->data;
|
||||
memcpy(p, d, len);
|
||||
p += len;
|
||||
if (len > 0)
|
||||
p[-1] &= (0xff << bits);
|
||||
*pp = p;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
ASN1_BIT_STRING *c2i_ASN1_BIT_STRING(ASN1_BIT_STRING **a,
|
||||
const unsigned char **pp, long len)
|
||||
{
|
||||
ASN1_BIT_STRING *ret=NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *s;
|
||||
int i;
|
||||
const unsigned char **pp, long len)
|
||||
{
|
||||
ASN1_BIT_STRING *ret = NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *s;
|
||||
int i;
|
||||
|
||||
if (len < 1)
|
||||
{
|
||||
i=ASN1_R_STRING_TOO_SHORT;
|
||||
goto err;
|
||||
}
|
||||
if (len < 1) {
|
||||
i = ASN1_R_STRING_TOO_SHORT;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((a == NULL) || ((*a) == NULL))
|
||||
{
|
||||
if ((ret=M_ASN1_BIT_STRING_new()) == NULL) return(NULL);
|
||||
}
|
||||
else
|
||||
ret=(*a);
|
||||
if ((a == NULL) || ((*a) == NULL)) {
|
||||
if ((ret = M_ASN1_BIT_STRING_new()) == NULL)
|
||||
return (NULL);
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
p= *pp;
|
||||
i= *(p++);
|
||||
/* We do this to preserve the settings. If we modify
|
||||
* the settings, via the _set_bit function, we will recalculate
|
||||
* on output */
|
||||
ret->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear */
|
||||
ret->flags|=(ASN1_STRING_FLAG_BITS_LEFT|(i&0x07)); /* set */
|
||||
p = *pp;
|
||||
i = *(p++);
|
||||
if (i > 7) {
|
||||
i = ASN1_R_INVALID_BIT_STRING_BITS_LEFT;
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* We do this to preserve the settings. If we modify the settings, via
|
||||
* the _set_bit function, we will recalculate on output
|
||||
*/
|
||||
ret->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear */
|
||||
ret->flags |= (ASN1_STRING_FLAG_BITS_LEFT | i); /* set */
|
||||
|
||||
if (len-- > 1) /* using one because of the bits left byte */
|
||||
{
|
||||
s=(unsigned char *)OPENSSL_malloc((int)len);
|
||||
if (s == NULL)
|
||||
{
|
||||
i=ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
memcpy(s,p,(int)len);
|
||||
s[len-1]&=(0xff<<i);
|
||||
p+=len;
|
||||
}
|
||||
else
|
||||
s=NULL;
|
||||
if (len-- > 1) { /* using one because of the bits left byte */
|
||||
s = (unsigned char *)OPENSSL_malloc((int)len);
|
||||
if (s == NULL) {
|
||||
i = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
memcpy(s, p, (int)len);
|
||||
s[len - 1] &= (0xff << i);
|
||||
p += len;
|
||||
} else
|
||||
s = NULL;
|
||||
|
||||
ret->length=(int)len;
|
||||
if (ret->data != NULL) OPENSSL_free(ret->data);
|
||||
ret->data=s;
|
||||
ret->type=V_ASN1_BIT_STRING;
|
||||
if (a != NULL) (*a)=ret;
|
||||
*pp=p;
|
||||
return(ret);
|
||||
err:
|
||||
ASN1err(ASN1_F_C2I_ASN1_BIT_STRING,i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_BIT_STRING_free(ret);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
|
||||
*/
|
||||
int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
|
||||
{
|
||||
int w,v,iv;
|
||||
unsigned char *c;
|
||||
|
||||
w=n/8;
|
||||
v=1<<(7-(n&0x07));
|
||||
iv= ~v;
|
||||
if (!value) v=0;
|
||||
|
||||
if (a == NULL)
|
||||
return 0;
|
||||
|
||||
a->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07); /* clear, set on write */
|
||||
|
||||
if ((a->length < (w+1)) || (a->data == NULL))
|
||||
{
|
||||
if (!value) return(1); /* Don't need to set */
|
||||
if (a->data == NULL)
|
||||
c=(unsigned char *)OPENSSL_malloc(w+1);
|
||||
else
|
||||
c=(unsigned char *)OPENSSL_realloc_clean(a->data,
|
||||
a->length,
|
||||
w+1);
|
||||
if (c == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT,ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (w+1-a->length > 0) memset(c+a->length, 0, w+1-a->length);
|
||||
a->data=c;
|
||||
a->length=w+1;
|
||||
}
|
||||
a->data[w]=((a->data[w])&iv)|v;
|
||||
while ((a->length > 0) && (a->data[a->length-1] == 0))
|
||||
a->length--;
|
||||
return(1);
|
||||
}
|
||||
|
||||
int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
|
||||
{
|
||||
int w,v;
|
||||
|
||||
w=n/8;
|
||||
v=1<<(7-(n&0x07));
|
||||
if ((a == NULL) || (a->length < (w+1)) || (a->data == NULL))
|
||||
return(0);
|
||||
return((a->data[w]&v) != 0);
|
||||
}
|
||||
ret->length = (int)len;
|
||||
if (ret->data != NULL)
|
||||
OPENSSL_free(ret->data);
|
||||
ret->data = s;
|
||||
ret->type = V_ASN1_BIT_STRING;
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = p;
|
||||
return (ret);
|
||||
err:
|
||||
ASN1err(ASN1_F_C2I_ASN1_BIT_STRING, i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_BIT_STRING_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if the given bit string contains only bits specified by
|
||||
* These next 2 functions from Goetz Babin-Ebell <babinebell@trustcenter.de>
|
||||
*/
|
||||
int ASN1_BIT_STRING_set_bit(ASN1_BIT_STRING *a, int n, int value)
|
||||
{
|
||||
int w, v, iv;
|
||||
unsigned char *c;
|
||||
|
||||
w = n / 8;
|
||||
v = 1 << (7 - (n & 0x07));
|
||||
iv = ~v;
|
||||
if (!value)
|
||||
v = 0;
|
||||
|
||||
if (a == NULL)
|
||||
return 0;
|
||||
|
||||
a->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07); /* clear, set on write */
|
||||
|
||||
if ((a->length < (w + 1)) || (a->data == NULL)) {
|
||||
if (!value)
|
||||
return (1); /* Don't need to set */
|
||||
if (a->data == NULL)
|
||||
c = (unsigned char *)OPENSSL_malloc(w + 1);
|
||||
else
|
||||
c = (unsigned char *)OPENSSL_realloc_clean(a->data,
|
||||
a->length, w + 1);
|
||||
if (c == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_BIT_STRING_SET_BIT, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (w + 1 - a->length > 0)
|
||||
memset(c + a->length, 0, w + 1 - a->length);
|
||||
a->data = c;
|
||||
a->length = w + 1;
|
||||
}
|
||||
a->data[w] = ((a->data[w]) & iv) | v;
|
||||
while ((a->length > 0) && (a->data[a->length - 1] == 0))
|
||||
a->length--;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int ASN1_BIT_STRING_get_bit(ASN1_BIT_STRING *a, int n)
|
||||
{
|
||||
int w, v;
|
||||
|
||||
w = n / 8;
|
||||
v = 1 << (7 - (n & 0x07));
|
||||
if ((a == NULL) || (a->length < (w + 1)) || (a->data == NULL))
|
||||
return (0);
|
||||
return ((a->data[w] & v) != 0);
|
||||
}
|
||||
|
||||
/*
|
||||
* Checks if the given bit string contains only bits specified by
|
||||
* the flags vector. Returns 0 if there is at least one bit set in 'a'
|
||||
* which is not specified in 'flags', 1 otherwise.
|
||||
* 'len' is the length of 'flags'.
|
||||
*/
|
||||
int ASN1_BIT_STRING_check(ASN1_BIT_STRING *a,
|
||||
unsigned char *flags, int flags_len)
|
||||
{
|
||||
int i, ok;
|
||||
/* Check if there is one bit set at all. */
|
||||
if (!a || !a->data) return 1;
|
||||
unsigned char *flags, int flags_len)
|
||||
{
|
||||
int i, ok;
|
||||
/* Check if there is one bit set at all. */
|
||||
if (!a || !a->data)
|
||||
return 1;
|
||||
|
||||
/* Check each byte of the internal representation of the bit string. */
|
||||
ok = 1;
|
||||
for (i = 0; i < a->length && ok; ++i)
|
||||
{
|
||||
unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
|
||||
/* We are done if there is an unneeded bit set. */
|
||||
ok = (a->data[i] & mask) == 0;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
/*
|
||||
* Check each byte of the internal representation of the bit string.
|
||||
*/
|
||||
ok = 1;
|
||||
for (i = 0; i < a->length && ok; ++i) {
|
||||
unsigned char mask = i < flags_len ? ~flags[i] : 0xff;
|
||||
/* We are done if there is an unneeded bit set. */
|
||||
ok = (a->data[i] & mask) == 0;
|
||||
}
|
||||
return ok;
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -61,54 +61,51 @@
|
||||
#include <openssl/asn1t.h>
|
||||
|
||||
int i2d_ASN1_BOOLEAN(int a, unsigned char **pp)
|
||||
{
|
||||
int r;
|
||||
unsigned char *p;
|
||||
{
|
||||
int r;
|
||||
unsigned char *p;
|
||||
|
||||
r=ASN1_object_size(0,1,V_ASN1_BOOLEAN);
|
||||
if (pp == NULL) return(r);
|
||||
p= *pp;
|
||||
r = ASN1_object_size(0, 1, V_ASN1_BOOLEAN);
|
||||
if (pp == NULL)
|
||||
return (r);
|
||||
p = *pp;
|
||||
|
||||
ASN1_put_object(&p,0,1,V_ASN1_BOOLEAN,V_ASN1_UNIVERSAL);
|
||||
*(p++)= (unsigned char)a;
|
||||
*pp=p;
|
||||
return(r);
|
||||
}
|
||||
ASN1_put_object(&p, 0, 1, V_ASN1_BOOLEAN, V_ASN1_UNIVERSAL);
|
||||
*(p++) = (unsigned char)a;
|
||||
*pp = p;
|
||||
return (r);
|
||||
}
|
||||
|
||||
int d2i_ASN1_BOOLEAN(int *a, const unsigned char **pp, long length)
|
||||
{
|
||||
int ret= -1;
|
||||
const unsigned char *p;
|
||||
long len;
|
||||
int inf,tag,xclass;
|
||||
int i=0;
|
||||
{
|
||||
int ret = -1;
|
||||
const unsigned char *p;
|
||||
long len;
|
||||
int inf, tag, xclass;
|
||||
int i = 0;
|
||||
|
||||
p= *pp;
|
||||
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
|
||||
if (inf & 0x80)
|
||||
{
|
||||
i=ASN1_R_BAD_OBJECT_HEADER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tag != V_ASN1_BOOLEAN)
|
||||
{
|
||||
i=ASN1_R_EXPECTING_A_BOOLEAN;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (len != 1)
|
||||
{
|
||||
i=ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
|
||||
goto err;
|
||||
}
|
||||
ret= (int)*(p++);
|
||||
if (a != NULL) (*a)=ret;
|
||||
*pp=p;
|
||||
return(ret);
|
||||
err:
|
||||
ASN1err(ASN1_F_D2I_ASN1_BOOLEAN,i);
|
||||
return(ret);
|
||||
}
|
||||
p = *pp;
|
||||
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
|
||||
if (inf & 0x80) {
|
||||
i = ASN1_R_BAD_OBJECT_HEADER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tag != V_ASN1_BOOLEAN) {
|
||||
i = ASN1_R_EXPECTING_A_BOOLEAN;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (len != 1) {
|
||||
i = ASN1_R_BOOLEAN_IS_WRONG_LENGTH;
|
||||
goto err;
|
||||
}
|
||||
ret = (int)*(p++);
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = p;
|
||||
return (ret);
|
||||
err:
|
||||
ASN1err(ASN1_F_D2I_ASN1_BOOLEAN, i);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -61,254 +61,246 @@
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c);
|
||||
/* type is a 'bitmap' of acceptable string types.
|
||||
/*
|
||||
* type is a 'bitmap' of acceptable string types.
|
||||
*/
|
||||
ASN1_STRING *d2i_ASN1_type_bytes(ASN1_STRING **a, const unsigned char **pp,
|
||||
long length, int type)
|
||||
{
|
||||
ASN1_STRING *ret=NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *s;
|
||||
long len;
|
||||
int inf,tag,xclass;
|
||||
int i=0;
|
||||
long length, int type)
|
||||
{
|
||||
ASN1_STRING *ret = NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *s;
|
||||
long len;
|
||||
int inf, tag, xclass;
|
||||
int i = 0;
|
||||
|
||||
p= *pp;
|
||||
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
|
||||
if (inf & 0x80) goto err;
|
||||
p = *pp;
|
||||
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
|
||||
if (inf & 0x80)
|
||||
goto err;
|
||||
|
||||
if (tag >= 32)
|
||||
{
|
||||
i=ASN1_R_TAG_VALUE_TOO_HIGH;
|
||||
goto err;
|
||||
}
|
||||
if (!(ASN1_tag2bit(tag) & type))
|
||||
{
|
||||
i=ASN1_R_WRONG_TYPE;
|
||||
goto err;
|
||||
}
|
||||
if (tag >= 32) {
|
||||
i = ASN1_R_TAG_VALUE_TOO_HIGH;
|
||||
goto err;
|
||||
}
|
||||
if (!(ASN1_tag2bit(tag) & type)) {
|
||||
i = ASN1_R_WRONG_TYPE;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* If a bit-string, exit early */
|
||||
if (tag == V_ASN1_BIT_STRING)
|
||||
return(d2i_ASN1_BIT_STRING(a,pp,length));
|
||||
/* If a bit-string, exit early */
|
||||
if (tag == V_ASN1_BIT_STRING)
|
||||
return (d2i_ASN1_BIT_STRING(a, pp, length));
|
||||
|
||||
if ((a == NULL) || ((*a) == NULL))
|
||||
{
|
||||
if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
|
||||
}
|
||||
else
|
||||
ret=(*a);
|
||||
if ((a == NULL) || ((*a) == NULL)) {
|
||||
if ((ret = ASN1_STRING_new()) == NULL)
|
||||
return (NULL);
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
if (len != 0)
|
||||
{
|
||||
s=(unsigned char *)OPENSSL_malloc((int)len+1);
|
||||
if (s == NULL)
|
||||
{
|
||||
i=ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
memcpy(s,p,(int)len);
|
||||
s[len]='\0';
|
||||
p+=len;
|
||||
}
|
||||
else
|
||||
s=NULL;
|
||||
if (len != 0) {
|
||||
s = (unsigned char *)OPENSSL_malloc((int)len + 1);
|
||||
if (s == NULL) {
|
||||
i = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
memcpy(s, p, (int)len);
|
||||
s[len] = '\0';
|
||||
p += len;
|
||||
} else
|
||||
s = NULL;
|
||||
|
||||
if (ret->data != NULL) OPENSSL_free(ret->data);
|
||||
ret->length=(int)len;
|
||||
ret->data=s;
|
||||
ret->type=tag;
|
||||
if (a != NULL) (*a)=ret;
|
||||
*pp=p;
|
||||
return(ret);
|
||||
err:
|
||||
ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES,i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
ASN1_STRING_free(ret);
|
||||
return(NULL);
|
||||
}
|
||||
if (ret->data != NULL)
|
||||
OPENSSL_free(ret->data);
|
||||
ret->length = (int)len;
|
||||
ret->data = s;
|
||||
ret->type = tag;
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = p;
|
||||
return (ret);
|
||||
err:
|
||||
ASN1err(ASN1_F_D2I_ASN1_TYPE_BYTES, i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
ASN1_STRING_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int i2d_ASN1_bytes(ASN1_STRING *a, unsigned char **pp, int tag, int xclass)
|
||||
{
|
||||
int ret,r,constructed;
|
||||
unsigned char *p;
|
||||
{
|
||||
int ret, r, constructed;
|
||||
unsigned char *p;
|
||||
|
||||
if (a == NULL) return(0);
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
|
||||
if (tag == V_ASN1_BIT_STRING)
|
||||
return(i2d_ASN1_BIT_STRING(a,pp));
|
||||
|
||||
ret=a->length;
|
||||
r=ASN1_object_size(0,ret,tag);
|
||||
if (pp == NULL) return(r);
|
||||
p= *pp;
|
||||
if (tag == V_ASN1_BIT_STRING)
|
||||
return (i2d_ASN1_BIT_STRING(a, pp));
|
||||
|
||||
if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
|
||||
constructed=1;
|
||||
else
|
||||
constructed=0;
|
||||
ASN1_put_object(&p,constructed,ret,tag,xclass);
|
||||
memcpy(p,a->data,a->length);
|
||||
p+=a->length;
|
||||
*pp= p;
|
||||
return(r);
|
||||
}
|
||||
ret = a->length;
|
||||
r = ASN1_object_size(0, ret, tag);
|
||||
if (pp == NULL)
|
||||
return (r);
|
||||
p = *pp;
|
||||
|
||||
if ((tag == V_ASN1_SEQUENCE) || (tag == V_ASN1_SET))
|
||||
constructed = 1;
|
||||
else
|
||||
constructed = 0;
|
||||
ASN1_put_object(&p, constructed, ret, tag, xclass);
|
||||
memcpy(p, a->data, a->length);
|
||||
p += a->length;
|
||||
*pp = p;
|
||||
return (r);
|
||||
}
|
||||
|
||||
ASN1_STRING *d2i_ASN1_bytes(ASN1_STRING **a, const unsigned char **pp,
|
||||
long length, int Ptag, int Pclass)
|
||||
{
|
||||
ASN1_STRING *ret=NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *s;
|
||||
long len;
|
||||
int inf,tag,xclass;
|
||||
int i=0;
|
||||
long length, int Ptag, int Pclass)
|
||||
{
|
||||
ASN1_STRING *ret = NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *s;
|
||||
long len;
|
||||
int inf, tag, xclass;
|
||||
int i = 0;
|
||||
|
||||
if ((a == NULL) || ((*a) == NULL))
|
||||
{
|
||||
if ((ret=ASN1_STRING_new()) == NULL) return(NULL);
|
||||
}
|
||||
else
|
||||
ret=(*a);
|
||||
if ((a == NULL) || ((*a) == NULL)) {
|
||||
if ((ret = ASN1_STRING_new()) == NULL)
|
||||
return (NULL);
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
p= *pp;
|
||||
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
|
||||
if (inf & 0x80)
|
||||
{
|
||||
i=ASN1_R_BAD_OBJECT_HEADER;
|
||||
goto err;
|
||||
}
|
||||
p = *pp;
|
||||
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
|
||||
if (inf & 0x80) {
|
||||
i = ASN1_R_BAD_OBJECT_HEADER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tag != Ptag)
|
||||
{
|
||||
i=ASN1_R_WRONG_TAG;
|
||||
goto err;
|
||||
}
|
||||
if (tag != Ptag) {
|
||||
i = ASN1_R_WRONG_TAG;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (inf & V_ASN1_CONSTRUCTED)
|
||||
{
|
||||
ASN1_const_CTX c;
|
||||
if (inf & V_ASN1_CONSTRUCTED) {
|
||||
ASN1_const_CTX c;
|
||||
|
||||
c.pp=pp;
|
||||
c.p=p;
|
||||
c.inf=inf;
|
||||
c.slen=len;
|
||||
c.tag=Ptag;
|
||||
c.xclass=Pclass;
|
||||
c.max=(length == 0)?0:(p+length);
|
||||
if (!asn1_collate_primitive(ret,&c))
|
||||
goto err;
|
||||
else
|
||||
{
|
||||
p=c.p;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (len != 0)
|
||||
{
|
||||
if ((ret->length < len) || (ret->data == NULL))
|
||||
{
|
||||
if (ret->data != NULL) OPENSSL_free(ret->data);
|
||||
s=(unsigned char *)OPENSSL_malloc((int)len + 1);
|
||||
if (s == NULL)
|
||||
{
|
||||
i=ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
s=ret->data;
|
||||
memcpy(s,p,(int)len);
|
||||
s[len] = '\0';
|
||||
p+=len;
|
||||
}
|
||||
else
|
||||
{
|
||||
s=NULL;
|
||||
if (ret->data != NULL) OPENSSL_free(ret->data);
|
||||
}
|
||||
c.pp = pp;
|
||||
c.p = p;
|
||||
c.inf = inf;
|
||||
c.slen = len;
|
||||
c.tag = Ptag;
|
||||
c.xclass = Pclass;
|
||||
c.max = (length == 0) ? 0 : (p + length);
|
||||
if (!asn1_collate_primitive(ret, &c))
|
||||
goto err;
|
||||
else {
|
||||
p = c.p;
|
||||
}
|
||||
} else {
|
||||
if (len != 0) {
|
||||
if ((ret->length < len) || (ret->data == NULL)) {
|
||||
if (ret->data != NULL)
|
||||
OPENSSL_free(ret->data);
|
||||
s = (unsigned char *)OPENSSL_malloc((int)len + 1);
|
||||
if (s == NULL) {
|
||||
i = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
} else
|
||||
s = ret->data;
|
||||
memcpy(s, p, (int)len);
|
||||
s[len] = '\0';
|
||||
p += len;
|
||||
} else {
|
||||
s = NULL;
|
||||
if (ret->data != NULL)
|
||||
OPENSSL_free(ret->data);
|
||||
}
|
||||
|
||||
ret->length=(int)len;
|
||||
ret->data=s;
|
||||
ret->type=Ptag;
|
||||
}
|
||||
ret->length = (int)len;
|
||||
ret->data = s;
|
||||
ret->type = Ptag;
|
||||
}
|
||||
|
||||
if (a != NULL) (*a)=ret;
|
||||
*pp=p;
|
||||
return(ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
ASN1_STRING_free(ret);
|
||||
ASN1err(ASN1_F_D2I_ASN1_BYTES,i);
|
||||
return(NULL);
|
||||
}
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = p;
|
||||
return (ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
ASN1_STRING_free(ret);
|
||||
ASN1err(ASN1_F_D2I_ASN1_BYTES, i);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/* We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse
|
||||
* them into the one structure that is then returned */
|
||||
/* There have been a few bug fixes for this function from
|
||||
* Paul Keogh <paul.keogh@sse.ie>, many thanks to him */
|
||||
/*
|
||||
* We are about to parse 0..n d2i_ASN1_bytes objects, we are to collapse them
|
||||
* into the one structure that is then returned
|
||||
*/
|
||||
/*
|
||||
* There have been a few bug fixes for this function from Paul Keogh
|
||||
* <paul.keogh@sse.ie>, many thanks to him
|
||||
*/
|
||||
static int asn1_collate_primitive(ASN1_STRING *a, ASN1_const_CTX *c)
|
||||
{
|
||||
ASN1_STRING *os=NULL;
|
||||
BUF_MEM b;
|
||||
int num;
|
||||
{
|
||||
ASN1_STRING *os = NULL;
|
||||
BUF_MEM b;
|
||||
int num;
|
||||
|
||||
b.length=0;
|
||||
b.max=0;
|
||||
b.data=NULL;
|
||||
b.length = 0;
|
||||
b.max = 0;
|
||||
b.data = NULL;
|
||||
|
||||
if (a == NULL)
|
||||
{
|
||||
c->error=ERR_R_PASSED_NULL_PARAMETER;
|
||||
goto err;
|
||||
}
|
||||
if (a == NULL) {
|
||||
c->error = ERR_R_PASSED_NULL_PARAMETER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
num=0;
|
||||
for (;;)
|
||||
{
|
||||
if (c->inf & 1)
|
||||
{
|
||||
c->eos=ASN1_const_check_infinite_end(&c->p,
|
||||
(long)(c->max-c->p));
|
||||
if (c->eos) break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (c->slen <= 0) break;
|
||||
}
|
||||
num = 0;
|
||||
for (;;) {
|
||||
if (c->inf & 1) {
|
||||
c->eos = ASN1_const_check_infinite_end(&c->p,
|
||||
(long)(c->max - c->p));
|
||||
if (c->eos)
|
||||
break;
|
||||
} else {
|
||||
if (c->slen <= 0)
|
||||
break;
|
||||
}
|
||||
|
||||
c->q=c->p;
|
||||
if (d2i_ASN1_bytes(&os,&c->p,c->max-c->p,c->tag,c->xclass)
|
||||
== NULL)
|
||||
{
|
||||
c->error=ERR_R_ASN1_LIB;
|
||||
goto err;
|
||||
}
|
||||
c->q = c->p;
|
||||
if (d2i_ASN1_bytes(&os, &c->p, c->max - c->p, c->tag, c->xclass)
|
||||
== NULL) {
|
||||
c->error = ERR_R_ASN1_LIB;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!BUF_MEM_grow_clean(&b,num+os->length))
|
||||
{
|
||||
c->error=ERR_R_BUF_LIB;
|
||||
goto err;
|
||||
}
|
||||
memcpy(&(b.data[num]),os->data,os->length);
|
||||
if (!(c->inf & 1))
|
||||
c->slen-=(c->p-c->q);
|
||||
num+=os->length;
|
||||
}
|
||||
if (!BUF_MEM_grow_clean(&b, num + os->length)) {
|
||||
c->error = ERR_R_BUF_LIB;
|
||||
goto err;
|
||||
}
|
||||
memcpy(&(b.data[num]), os->data, os->length);
|
||||
if (!(c->inf & 1))
|
||||
c->slen -= (c->p - c->q);
|
||||
num += os->length;
|
||||
}
|
||||
|
||||
if (!asn1_const_Finish(c)) goto err;
|
||||
|
||||
a->length=num;
|
||||
if (a->data != NULL) OPENSSL_free(a->data);
|
||||
a->data=(unsigned char *)b.data;
|
||||
if (os != NULL) ASN1_STRING_free(os);
|
||||
return(1);
|
||||
err:
|
||||
ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE,c->error);
|
||||
if (os != NULL) ASN1_STRING_free(os);
|
||||
if (b.data != NULL) OPENSSL_free(b.data);
|
||||
return(0);
|
||||
}
|
||||
if (!asn1_const_Finish(c))
|
||||
goto err;
|
||||
|
||||
a->length = num;
|
||||
if (a->data != NULL)
|
||||
OPENSSL_free(a->data);
|
||||
a->data = (unsigned char *)b.data;
|
||||
if (os != NULL)
|
||||
ASN1_STRING_free(os);
|
||||
return (1);
|
||||
err:
|
||||
ASN1err(ASN1_F_ASN1_COLLATE_PRIMITIVE, c->error);
|
||||
if (os != NULL)
|
||||
ASN1_STRING_free(os);
|
||||
if (b.data != NULL)
|
||||
OPENSSL_free(b.data);
|
||||
return (0);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -65,222 +65,204 @@
|
||||
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb);
|
||||
|
||||
#ifndef NO_OLD_ASN1
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
# ifndef OPENSSL_NO_FP_API
|
||||
|
||||
void *ASN1_d2i_fp(void *(*xnew)(void), d2i_of_void *d2i, FILE *in, void **x)
|
||||
{
|
||||
BIO *b;
|
||||
void *ret;
|
||||
void *ASN1_d2i_fp(void *(*xnew) (void), d2i_of_void *d2i, FILE *in, void **x)
|
||||
{
|
||||
BIO *b;
|
||||
void *ret;
|
||||
|
||||
if ((b=BIO_new(BIO_s_file())) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_D2I_FP,ERR_R_BUF_LIB);
|
||||
return(NULL);
|
||||
}
|
||||
BIO_set_fp(b,in,BIO_NOCLOSE);
|
||||
ret=ASN1_d2i_bio(xnew,d2i,b,x);
|
||||
BIO_free(b);
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_D2I_FP, ERR_R_BUF_LIB);
|
||||
return (NULL);
|
||||
}
|
||||
BIO_set_fp(b, in, BIO_NOCLOSE);
|
||||
ret = ASN1_d2i_bio(xnew, d2i, b, x);
|
||||
BIO_free(b);
|
||||
return (ret);
|
||||
}
|
||||
# endif
|
||||
|
||||
void *ASN1_d2i_bio(void *(*xnew)(void), d2i_of_void *d2i, BIO *in, void **x)
|
||||
{
|
||||
BUF_MEM *b = NULL;
|
||||
const unsigned char *p;
|
||||
void *ret=NULL;
|
||||
int len;
|
||||
void *ASN1_d2i_bio(void *(*xnew) (void), d2i_of_void *d2i, BIO *in, void **x)
|
||||
{
|
||||
BUF_MEM *b = NULL;
|
||||
const unsigned char *p;
|
||||
void *ret = NULL;
|
||||
int len;
|
||||
|
||||
len = asn1_d2i_read_bio(in, &b);
|
||||
if(len < 0) goto err;
|
||||
len = asn1_d2i_read_bio(in, &b);
|
||||
if (len < 0)
|
||||
goto err;
|
||||
|
||||
p=(unsigned char *)b->data;
|
||||
ret=d2i(x,&p,len);
|
||||
err:
|
||||
if (b != NULL) BUF_MEM_free(b);
|
||||
return(ret);
|
||||
}
|
||||
p = (unsigned char *)b->data;
|
||||
ret = d2i(x, &p, len);
|
||||
err:
|
||||
if (b != NULL)
|
||||
BUF_MEM_free(b);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
void *ASN1_item_d2i_bio(const ASN1_ITEM *it, BIO *in, void *x)
|
||||
{
|
||||
BUF_MEM *b = NULL;
|
||||
const unsigned char *p;
|
||||
void *ret=NULL;
|
||||
int len;
|
||||
{
|
||||
BUF_MEM *b = NULL;
|
||||
const unsigned char *p;
|
||||
void *ret = NULL;
|
||||
int len;
|
||||
|
||||
len = asn1_d2i_read_bio(in, &b);
|
||||
if(len < 0) goto err;
|
||||
len = asn1_d2i_read_bio(in, &b);
|
||||
if (len < 0)
|
||||
goto err;
|
||||
|
||||
p=(const unsigned char *)b->data;
|
||||
ret=ASN1_item_d2i(x,&p,len, it);
|
||||
err:
|
||||
if (b != NULL) BUF_MEM_free(b);
|
||||
return(ret);
|
||||
}
|
||||
p = (const unsigned char *)b->data;
|
||||
ret = ASN1_item_d2i(x, &p, len, it);
|
||||
err:
|
||||
if (b != NULL)
|
||||
BUF_MEM_free(b);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
void *ASN1_item_d2i_fp(const ASN1_ITEM *it, FILE *in, void *x)
|
||||
{
|
||||
BIO *b;
|
||||
char *ret;
|
||||
{
|
||||
BIO *b;
|
||||
char *ret;
|
||||
|
||||
if ((b=BIO_new(BIO_s_file())) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_D2I_FP,ERR_R_BUF_LIB);
|
||||
return(NULL);
|
||||
}
|
||||
BIO_set_fp(b,in,BIO_NOCLOSE);
|
||||
ret=ASN1_item_d2i_bio(it,b,x);
|
||||
BIO_free(b);
|
||||
return(ret);
|
||||
}
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_D2I_FP, ERR_R_BUF_LIB);
|
||||
return (NULL);
|
||||
}
|
||||
BIO_set_fp(b, in, BIO_NOCLOSE);
|
||||
ret = ASN1_item_d2i_bio(it, b, x);
|
||||
BIO_free(b);
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
#define HEADER_SIZE 8
|
||||
static int asn1_d2i_read_bio(BIO *in, BUF_MEM **pb)
|
||||
{
|
||||
BUF_MEM *b;
|
||||
unsigned char *p;
|
||||
int i;
|
||||
ASN1_const_CTX c;
|
||||
size_t want=HEADER_SIZE;
|
||||
int eos=0;
|
||||
size_t off=0;
|
||||
size_t len=0;
|
||||
{
|
||||
BUF_MEM *b;
|
||||
unsigned char *p;
|
||||
int i;
|
||||
ASN1_const_CTX c;
|
||||
size_t want = HEADER_SIZE;
|
||||
int eos = 0;
|
||||
size_t off = 0;
|
||||
size_t len = 0;
|
||||
|
||||
b=BUF_MEM_new();
|
||||
if (b == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
b = BUF_MEM_new();
|
||||
if (b == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
ERR_clear_error();
|
||||
for (;;)
|
||||
{
|
||||
if (want >= (len-off))
|
||||
{
|
||||
want-=(len-off);
|
||||
ERR_clear_error();
|
||||
for (;;) {
|
||||
if (want >= (len - off)) {
|
||||
want -= (len - off);
|
||||
|
||||
if (len + want < len || !BUF_MEM_grow_clean(b,len+want))
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
i=BIO_read(in,&(b->data[len]),want);
|
||||
if ((i < 0) && ((len-off) == 0))
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_NOT_ENOUGH_DATA);
|
||||
goto err;
|
||||
}
|
||||
if (i > 0)
|
||||
{
|
||||
if (len+i < len)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
len+=i;
|
||||
}
|
||||
}
|
||||
/* else data already loaded */
|
||||
if (len + want < len || !BUF_MEM_grow_clean(b, len + want)) {
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
i = BIO_read(in, &(b->data[len]), want);
|
||||
if ((i < 0) && ((len - off) == 0)) {
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_NOT_ENOUGH_DATA);
|
||||
goto err;
|
||||
}
|
||||
if (i > 0) {
|
||||
if (len + i < len) {
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
len += i;
|
||||
}
|
||||
}
|
||||
/* else data already loaded */
|
||||
|
||||
p=(unsigned char *)&(b->data[off]);
|
||||
c.p=p;
|
||||
c.inf=ASN1_get_object(&(c.p),&(c.slen),&(c.tag),&(c.xclass),
|
||||
len-off);
|
||||
if (c.inf & 0x80)
|
||||
{
|
||||
unsigned long e;
|
||||
p = (unsigned char *)&(b->data[off]);
|
||||
c.p = p;
|
||||
c.inf = ASN1_get_object(&(c.p), &(c.slen), &(c.tag), &(c.xclass),
|
||||
len - off);
|
||||
if (c.inf & 0x80) {
|
||||
unsigned long e;
|
||||
|
||||
e=ERR_GET_REASON(ERR_peek_error());
|
||||
if (e != ASN1_R_TOO_LONG)
|
||||
goto err;
|
||||
else
|
||||
ERR_clear_error(); /* clear error */
|
||||
}
|
||||
i=c.p-p;/* header length */
|
||||
off+=i; /* end of data */
|
||||
e = ERR_GET_REASON(ERR_peek_error());
|
||||
if (e != ASN1_R_TOO_LONG)
|
||||
goto err;
|
||||
else
|
||||
ERR_clear_error(); /* clear error */
|
||||
}
|
||||
i = c.p - p; /* header length */
|
||||
off += i; /* end of data */
|
||||
|
||||
if (c.inf & 1)
|
||||
{
|
||||
/* no data body so go round again */
|
||||
eos++;
|
||||
if (eos < 0)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_HEADER_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
want=HEADER_SIZE;
|
||||
}
|
||||
else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC))
|
||||
{
|
||||
/* eos value, so go back and read another header */
|
||||
eos--;
|
||||
if (eos <= 0)
|
||||
break;
|
||||
else
|
||||
want=HEADER_SIZE;
|
||||
}
|
||||
else
|
||||
{
|
||||
/* suck in c.slen bytes of data */
|
||||
want=c.slen;
|
||||
if (want > (len-off))
|
||||
{
|
||||
want-=(len-off);
|
||||
if (want > INT_MAX /* BIO_read takes an int length */ ||
|
||||
len+want < len)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
if (!BUF_MEM_grow_clean(b,len+want))
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
while (want > 0)
|
||||
{
|
||||
i=BIO_read(in,&(b->data[len]),want);
|
||||
if (i <= 0)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
|
||||
ASN1_R_NOT_ENOUGH_DATA);
|
||||
goto err;
|
||||
}
|
||||
/* This can't overflow because
|
||||
* |len+want| didn't overflow. */
|
||||
len+=i;
|
||||
want-=i;
|
||||
}
|
||||
}
|
||||
if (off + c.slen < off)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
off+=c.slen;
|
||||
if (eos <= 0)
|
||||
{
|
||||
break;
|
||||
}
|
||||
else
|
||||
want=HEADER_SIZE;
|
||||
}
|
||||
}
|
||||
if (c.inf & 1) {
|
||||
/* no data body so go round again */
|
||||
eos++;
|
||||
if (eos < 0) {
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_HEADER_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
want = HEADER_SIZE;
|
||||
} else if (eos && (c.slen == 0) && (c.tag == V_ASN1_EOC)) {
|
||||
/* eos value, so go back and read another header */
|
||||
eos--;
|
||||
if (eos <= 0)
|
||||
break;
|
||||
else
|
||||
want = HEADER_SIZE;
|
||||
} else {
|
||||
/* suck in c.slen bytes of data */
|
||||
want = c.slen;
|
||||
if (want > (len - off)) {
|
||||
want -= (len - off);
|
||||
if (want > INT_MAX /* BIO_read takes an int length */ ||
|
||||
len + want < len) {
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
if (!BUF_MEM_grow_clean(b, len + want)) {
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
while (want > 0) {
|
||||
i = BIO_read(in, &(b->data[len]), want);
|
||||
if (i <= 0) {
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,
|
||||
ASN1_R_NOT_ENOUGH_DATA);
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* This can't overflow because |len+want| didn't
|
||||
* overflow.
|
||||
*/
|
||||
len += i;
|
||||
want -= i;
|
||||
}
|
||||
}
|
||||
if (off + c.slen < off) {
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
off += c.slen;
|
||||
if (eos <= 0) {
|
||||
break;
|
||||
} else
|
||||
want = HEADER_SIZE;
|
||||
}
|
||||
}
|
||||
|
||||
if (off > INT_MAX)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO,ASN1_R_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
if (off > INT_MAX) {
|
||||
ASN1err(ASN1_F_ASN1_D2I_READ_BIO, ASN1_R_TOO_LONG);
|
||||
goto err;
|
||||
}
|
||||
|
||||
*pb = b;
|
||||
return off;
|
||||
err:
|
||||
if (b != NULL) BUF_MEM_free(b);
|
||||
return -1;
|
||||
}
|
||||
*pb = b;
|
||||
return off;
|
||||
err:
|
||||
if (b != NULL)
|
||||
BUF_MEM_free(b);
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -73,41 +73,39 @@
|
||||
#ifndef NO_ASN1_OLD
|
||||
|
||||
int ASN1_digest(i2d_of_void *i2d, const EVP_MD *type, char *data,
|
||||
unsigned char *md, unsigned int *len)
|
||||
{
|
||||
int i;
|
||||
unsigned char *str,*p;
|
||||
unsigned char *md, unsigned int *len)
|
||||
{
|
||||
int i;
|
||||
unsigned char *str, *p;
|
||||
|
||||
i=i2d(data,NULL);
|
||||
if ((str=(unsigned char *)OPENSSL_malloc(i)) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_DIGEST,ERR_R_MALLOC_FAILURE);
|
||||
return(0);
|
||||
}
|
||||
p=str;
|
||||
i2d(data,&p);
|
||||
i = i2d(data, NULL);
|
||||
if ((str = (unsigned char *)OPENSSL_malloc(i)) == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_DIGEST, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
p = str;
|
||||
i2d(data, &p);
|
||||
|
||||
if (!EVP_Digest(str, i, md, len, type, NULL))
|
||||
return 0;
|
||||
OPENSSL_free(str);
|
||||
return(1);
|
||||
}
|
||||
if (!EVP_Digest(str, i, md, len, type, NULL))
|
||||
return 0;
|
||||
OPENSSL_free(str);
|
||||
return (1);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int ASN1_item_digest(const ASN1_ITEM *it, const EVP_MD *type, void *asn,
|
||||
unsigned char *md, unsigned int *len)
|
||||
{
|
||||
int i;
|
||||
unsigned char *str = NULL;
|
||||
unsigned char *md, unsigned int *len)
|
||||
{
|
||||
int i;
|
||||
unsigned char *str = NULL;
|
||||
|
||||
i=ASN1_item_i2d(asn,&str, it);
|
||||
if (!str) return(0);
|
||||
|
||||
if (!EVP_Digest(str, i, md, len, type, NULL))
|
||||
return 0;
|
||||
OPENSSL_free(str);
|
||||
return(1);
|
||||
}
|
||||
i = ASN1_item_i2d(asn, &str, it);
|
||||
if (!str)
|
||||
return (0);
|
||||
|
||||
if (!EVP_Digest(str, i, md, len, type, NULL))
|
||||
return 0;
|
||||
OPENSSL_free(str);
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -63,47 +63,55 @@
|
||||
#ifndef NO_OLD_ASN1
|
||||
|
||||
void *ASN1_dup(i2d_of_void *i2d, d2i_of_void *d2i, void *x)
|
||||
{
|
||||
unsigned char *b,*p;
|
||||
const unsigned char *p2;
|
||||
int i;
|
||||
char *ret;
|
||||
{
|
||||
unsigned char *b, *p;
|
||||
const unsigned char *p2;
|
||||
int i;
|
||||
char *ret;
|
||||
|
||||
if (x == NULL) return(NULL);
|
||||
if (x == NULL)
|
||||
return (NULL);
|
||||
|
||||
i=i2d(x,NULL);
|
||||
b=OPENSSL_malloc(i+10);
|
||||
if (b == NULL)
|
||||
{ ASN1err(ASN1_F_ASN1_DUP,ERR_R_MALLOC_FAILURE); return(NULL); }
|
||||
p= b;
|
||||
i=i2d(x,&p);
|
||||
p2= b;
|
||||
ret=d2i(NULL,&p2,i);
|
||||
OPENSSL_free(b);
|
||||
return(ret);
|
||||
}
|
||||
i = i2d(x, NULL);
|
||||
b = OPENSSL_malloc(i + 10);
|
||||
if (b == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_DUP, ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
p = b;
|
||||
i = i2d(x, &p);
|
||||
p2 = b;
|
||||
ret = d2i(NULL, &p2, i);
|
||||
OPENSSL_free(b);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/* ASN1_ITEM version of dup: this follows the model above except we don't need
|
||||
* to allocate the buffer. At some point this could be rewritten to directly dup
|
||||
* the underlying structure instead of doing and encode and decode.
|
||||
/*
|
||||
* ASN1_ITEM version of dup: this follows the model above except we don't
|
||||
* need to allocate the buffer. At some point this could be rewritten to
|
||||
* directly dup the underlying structure instead of doing and encode and
|
||||
* decode.
|
||||
*/
|
||||
|
||||
void *ASN1_item_dup(const ASN1_ITEM *it, void *x)
|
||||
{
|
||||
unsigned char *b = NULL;
|
||||
const unsigned char *p;
|
||||
long i;
|
||||
void *ret;
|
||||
{
|
||||
unsigned char *b = NULL;
|
||||
const unsigned char *p;
|
||||
long i;
|
||||
void *ret;
|
||||
|
||||
if (x == NULL) return(NULL);
|
||||
if (x == NULL)
|
||||
return (NULL);
|
||||
|
||||
i=ASN1_item_i2d(x,&b,it);
|
||||
if (b == NULL)
|
||||
{ ASN1err(ASN1_F_ASN1_ITEM_DUP,ERR_R_MALLOC_FAILURE); return(NULL); }
|
||||
p= b;
|
||||
ret=ASN1_item_d2i(NULL,&p,i, it);
|
||||
OPENSSL_free(b);
|
||||
return(ret);
|
||||
}
|
||||
i = ASN1_item_i2d(x, &b, it);
|
||||
if (b == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_DUP, ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
p = b;
|
||||
ret = ASN1_item_d2i(NULL, &p, i, it);
|
||||
OPENSSL_free(b);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -61,122 +61,121 @@
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
/*
|
||||
/*
|
||||
* Code for ENUMERATED type: identical to INTEGER apart from a different tag.
|
||||
* for comments on encoding see a_int.c
|
||||
*/
|
||||
|
||||
int ASN1_ENUMERATED_set(ASN1_ENUMERATED *a, long v)
|
||||
{
|
||||
int j,k;
|
||||
unsigned int i;
|
||||
unsigned char buf[sizeof(long)+1];
|
||||
long d;
|
||||
{
|
||||
int j, k;
|
||||
unsigned int i;
|
||||
unsigned char buf[sizeof(long) + 1];
|
||||
long d;
|
||||
|
||||
a->type=V_ASN1_ENUMERATED;
|
||||
if (a->length < (int)(sizeof(long)+1))
|
||||
{
|
||||
if (a->data != NULL)
|
||||
OPENSSL_free(a->data);
|
||||
if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
|
||||
memset((char *)a->data,0,sizeof(long)+1);
|
||||
}
|
||||
if (a->data == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ENUMERATED_SET,ERR_R_MALLOC_FAILURE);
|
||||
return(0);
|
||||
}
|
||||
d=v;
|
||||
if (d < 0)
|
||||
{
|
||||
d= -d;
|
||||
a->type=V_ASN1_NEG_ENUMERATED;
|
||||
}
|
||||
a->type = V_ASN1_ENUMERATED;
|
||||
if (a->length < (int)(sizeof(long) + 1)) {
|
||||
if (a->data != NULL)
|
||||
OPENSSL_free(a->data);
|
||||
if ((a->data =
|
||||
(unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
|
||||
memset((char *)a->data, 0, sizeof(long) + 1);
|
||||
}
|
||||
if (a->data == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_ENUMERATED_SET, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
d = v;
|
||||
if (d < 0) {
|
||||
d = -d;
|
||||
a->type = V_ASN1_NEG_ENUMERATED;
|
||||
}
|
||||
|
||||
for (i=0; i<sizeof(long); i++)
|
||||
{
|
||||
if (d == 0) break;
|
||||
buf[i]=(int)d&0xff;
|
||||
d>>=8;
|
||||
}
|
||||
j=0;
|
||||
for (k=i-1; k >=0; k--)
|
||||
a->data[j++]=buf[k];
|
||||
a->length=j;
|
||||
return(1);
|
||||
}
|
||||
for (i = 0; i < sizeof(long); i++) {
|
||||
if (d == 0)
|
||||
break;
|
||||
buf[i] = (int)d & 0xff;
|
||||
d >>= 8;
|
||||
}
|
||||
j = 0;
|
||||
for (k = i - 1; k >= 0; k--)
|
||||
a->data[j++] = buf[k];
|
||||
a->length = j;
|
||||
return (1);
|
||||
}
|
||||
|
||||
long ASN1_ENUMERATED_get(ASN1_ENUMERATED *a)
|
||||
{
|
||||
int neg=0,i;
|
||||
long r=0;
|
||||
{
|
||||
int neg = 0, i;
|
||||
long r = 0;
|
||||
|
||||
if (a == NULL) return(0L);
|
||||
i=a->type;
|
||||
if (i == V_ASN1_NEG_ENUMERATED)
|
||||
neg=1;
|
||||
else if (i != V_ASN1_ENUMERATED)
|
||||
return -1;
|
||||
|
||||
if (a->length > (int)sizeof(long))
|
||||
{
|
||||
/* hmm... a bit ugly */
|
||||
return(0xffffffffL);
|
||||
}
|
||||
if (a->data == NULL)
|
||||
return 0;
|
||||
if (a == NULL)
|
||||
return (0L);
|
||||
i = a->type;
|
||||
if (i == V_ASN1_NEG_ENUMERATED)
|
||||
neg = 1;
|
||||
else if (i != V_ASN1_ENUMERATED)
|
||||
return -1;
|
||||
|
||||
for (i=0; i<a->length; i++)
|
||||
{
|
||||
r<<=8;
|
||||
r|=(unsigned char)a->data[i];
|
||||
}
|
||||
if (neg) r= -r;
|
||||
return(r);
|
||||
}
|
||||
if (a->length > (int)sizeof(long)) {
|
||||
/* hmm... a bit ugly */
|
||||
return (0xffffffffL);
|
||||
}
|
||||
if (a->data == NULL)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < a->length; i++) {
|
||||
r <<= 8;
|
||||
r |= (unsigned char)a->data[i];
|
||||
}
|
||||
if (neg)
|
||||
r = -r;
|
||||
return (r);
|
||||
}
|
||||
|
||||
ASN1_ENUMERATED *BN_to_ASN1_ENUMERATED(BIGNUM *bn, ASN1_ENUMERATED *ai)
|
||||
{
|
||||
ASN1_ENUMERATED *ret;
|
||||
int len,j;
|
||||
{
|
||||
ASN1_ENUMERATED *ret;
|
||||
int len, j;
|
||||
|
||||
if (ai == NULL)
|
||||
ret=M_ASN1_ENUMERATED_new();
|
||||
else
|
||||
ret=ai;
|
||||
if (ret == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_NESTED_ASN1_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if(BN_is_negative(bn)) ret->type = V_ASN1_NEG_ENUMERATED;
|
||||
else ret->type=V_ASN1_ENUMERATED;
|
||||
j=BN_num_bits(bn);
|
||||
len=((j == 0)?0:((j/8)+1));
|
||||
if (ret->length < len+4)
|
||||
{
|
||||
unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
|
||||
if (!new_data)
|
||||
{
|
||||
ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
ret->data=new_data;
|
||||
}
|
||||
if (ai == NULL)
|
||||
ret = M_ASN1_ENUMERATED_new();
|
||||
else
|
||||
ret = ai;
|
||||
if (ret == NULL) {
|
||||
ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_NESTED_ASN1_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_negative(bn))
|
||||
ret->type = V_ASN1_NEG_ENUMERATED;
|
||||
else
|
||||
ret->type = V_ASN1_ENUMERATED;
|
||||
j = BN_num_bits(bn);
|
||||
len = ((j == 0) ? 0 : ((j / 8) + 1));
|
||||
if (ret->length < len + 4) {
|
||||
unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
|
||||
if (!new_data) {
|
||||
ASN1err(ASN1_F_BN_TO_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
ret->data = new_data;
|
||||
}
|
||||
|
||||
ret->length=BN_bn2bin(bn,ret->data);
|
||||
return(ret);
|
||||
err:
|
||||
if (ret != ai) M_ASN1_ENUMERATED_free(ret);
|
||||
return(NULL);
|
||||
}
|
||||
ret->length = BN_bn2bin(bn, ret->data);
|
||||
return (ret);
|
||||
err:
|
||||
if (ret != ai)
|
||||
M_ASN1_ENUMERATED_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
BIGNUM *ASN1_ENUMERATED_to_BN(ASN1_ENUMERATED *ai, BIGNUM *bn)
|
||||
{
|
||||
BIGNUM *ret;
|
||||
{
|
||||
BIGNUM *ret;
|
||||
|
||||
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
|
||||
ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN,ASN1_R_BN_LIB);
|
||||
else if(ai->type == V_ASN1_NEG_ENUMERATED) BN_set_negative(ret,1);
|
||||
return(ret);
|
||||
}
|
||||
if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
|
||||
ASN1err(ASN1_F_ASN1_ENUMERATED_TO_BN, ASN1_R_BN_LIB);
|
||||
else if (ai->type == V_ASN1_NEG_ENUMERATED)
|
||||
BN_set_negative(ret, 1);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,14 +49,16 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
* [including the GNU Public Licence.]
|
||||
*/
|
||||
|
||||
/* GENERALIZEDTIME implementation, written by Steve Henson. Based on UTCTIME */
|
||||
/*
|
||||
* GENERALIZEDTIME implementation, written by Steve Henson. Based on UTCTIME
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <time.h>
|
||||
@ -67,197 +69,202 @@
|
||||
#if 0
|
||||
|
||||
int i2d_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME *a, unsigned char **pp)
|
||||
{
|
||||
#ifdef CHARSET_EBCDIC
|
||||
/* KLUDGE! We convert to ascii before writing DER */
|
||||
int len;
|
||||
char tmp[24];
|
||||
ASN1_STRING tmpstr = *(ASN1_STRING *)a;
|
||||
{
|
||||
# ifdef CHARSET_EBCDIC
|
||||
/* KLUDGE! We convert to ascii before writing DER */
|
||||
int len;
|
||||
char tmp[24];
|
||||
ASN1_STRING tmpstr = *(ASN1_STRING *)a;
|
||||
|
||||
len = tmpstr.length;
|
||||
ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len);
|
||||
tmpstr.data = tmp;
|
||||
|
||||
a = (ASN1_GENERALIZEDTIME *) &tmpstr;
|
||||
#endif
|
||||
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
|
||||
V_ASN1_GENERALIZEDTIME,V_ASN1_UNIVERSAL));
|
||||
}
|
||||
len = tmpstr.length;
|
||||
ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len);
|
||||
tmpstr.data = tmp;
|
||||
|
||||
a = (ASN1_GENERALIZEDTIME *)&tmpstr;
|
||||
# endif
|
||||
return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
|
||||
V_ASN1_GENERALIZEDTIME, V_ASN1_UNIVERSAL));
|
||||
}
|
||||
|
||||
ASN1_GENERALIZEDTIME *d2i_ASN1_GENERALIZEDTIME(ASN1_GENERALIZEDTIME **a,
|
||||
unsigned char **pp, long length)
|
||||
{
|
||||
ASN1_GENERALIZEDTIME *ret=NULL;
|
||||
unsigned char **pp,
|
||||
long length)
|
||||
{
|
||||
ASN1_GENERALIZEDTIME *ret = NULL;
|
||||
|
||||
ret=(ASN1_GENERALIZEDTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
|
||||
V_ASN1_GENERALIZEDTIME,V_ASN1_UNIVERSAL);
|
||||
if (ret == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME,ERR_R_NESTED_ASN1_ERROR);
|
||||
return(NULL);
|
||||
}
|
||||
#ifdef CHARSET_EBCDIC
|
||||
ascii2ebcdic(ret->data, ret->data, ret->length);
|
||||
#endif
|
||||
if (!ASN1_GENERALIZEDTIME_check(ret))
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME,ASN1_R_INVALID_TIME_FORMAT);
|
||||
goto err;
|
||||
}
|
||||
ret =
|
||||
(ASN1_GENERALIZEDTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length,
|
||||
V_ASN1_GENERALIZEDTIME,
|
||||
V_ASN1_UNIVERSAL);
|
||||
if (ret == NULL) {
|
||||
ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME, ERR_R_NESTED_ASN1_ERROR);
|
||||
return (NULL);
|
||||
}
|
||||
# ifdef CHARSET_EBCDIC
|
||||
ascii2ebcdic(ret->data, ret->data, ret->length);
|
||||
# endif
|
||||
if (!ASN1_GENERALIZEDTIME_check(ret)) {
|
||||
ASN1err(ASN1_F_D2I_ASN1_GENERALIZEDTIME, ASN1_R_INVALID_TIME_FORMAT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_GENERALIZEDTIME_free(ret);
|
||||
return(NULL);
|
||||
}
|
||||
return (ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_GENERALIZEDTIME_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int ASN1_GENERALIZEDTIME_check(ASN1_GENERALIZEDTIME *d)
|
||||
{
|
||||
static const int min[9]={ 0, 0, 1, 1, 0, 0, 0, 0, 0};
|
||||
static const int max[9]={99, 99,12,31,23,59,59,12,59};
|
||||
char *a;
|
||||
int n,i,l,o;
|
||||
{
|
||||
static const int min[9] = { 0, 0, 1, 1, 0, 0, 0, 0, 0 };
|
||||
static const int max[9] = { 99, 99, 12, 31, 23, 59, 59, 12, 59 };
|
||||
char *a;
|
||||
int n, i, l, o;
|
||||
|
||||
if (d->type != V_ASN1_GENERALIZEDTIME) return(0);
|
||||
l=d->length;
|
||||
a=(char *)d->data;
|
||||
o=0;
|
||||
/* GENERALIZEDTIME is similar to UTCTIME except the year is
|
||||
* represented as YYYY. This stuff treats everything as a two digit
|
||||
* field so make first two fields 00 to 99
|
||||
*/
|
||||
if (l < 13) goto err;
|
||||
for (i=0; i<7; i++)
|
||||
{
|
||||
if ((i == 6) && ((a[o] == 'Z') ||
|
||||
(a[o] == '+') || (a[o] == '-')))
|
||||
{ i++; break; }
|
||||
if ((a[o] < '0') || (a[o] > '9')) goto err;
|
||||
n= a[o]-'0';
|
||||
if (++o > l) goto err;
|
||||
if (d->type != V_ASN1_GENERALIZEDTIME)
|
||||
return (0);
|
||||
l = d->length;
|
||||
a = (char *)d->data;
|
||||
o = 0;
|
||||
/*
|
||||
* GENERALIZEDTIME is similar to UTCTIME except the year is represented
|
||||
* as YYYY. This stuff treats everything as a two digit field so make
|
||||
* first two fields 00 to 99
|
||||
*/
|
||||
if (l < 13)
|
||||
goto err;
|
||||
for (i = 0; i < 7; i++) {
|
||||
if ((i == 6) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = a[o] - '0';
|
||||
if (++o > l)
|
||||
goto err;
|
||||
|
||||
if ((a[o] < '0') || (a[o] > '9')) goto err;
|
||||
n=(n*10)+ a[o]-'0';
|
||||
if (++o > l) goto err;
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = (n * 10) + a[o] - '0';
|
||||
if (++o > l)
|
||||
goto err;
|
||||
|
||||
if ((n < min[i]) || (n > max[i])) goto err;
|
||||
}
|
||||
/* Optional fractional seconds: decimal point followed by one
|
||||
* or more digits.
|
||||
*/
|
||||
if (a[o] == '.')
|
||||
{
|
||||
if (++o > l) goto err;
|
||||
i = o;
|
||||
while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
|
||||
o++;
|
||||
/* Must have at least one digit after decimal point */
|
||||
if (i == o) goto err;
|
||||
}
|
||||
if ((n < min[i]) || (n > max[i]))
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* Optional fractional seconds: decimal point followed by one or more
|
||||
* digits.
|
||||
*/
|
||||
if (a[o] == '.') {
|
||||
if (++o > l)
|
||||
goto err;
|
||||
i = o;
|
||||
while ((a[o] >= '0') && (a[o] <= '9') && (o <= l))
|
||||
o++;
|
||||
/* Must have at least one digit after decimal point */
|
||||
if (i == o)
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (a[o] == 'Z')
|
||||
o++;
|
||||
else if ((a[o] == '+') || (a[o] == '-'))
|
||||
{
|
||||
o++;
|
||||
if (o+4 > l) goto err;
|
||||
for (i=7; i<9; i++)
|
||||
{
|
||||
if ((a[o] < '0') || (a[o] > '9')) goto err;
|
||||
n= a[o]-'0';
|
||||
o++;
|
||||
if ((a[o] < '0') || (a[o] > '9')) goto err;
|
||||
n=(n*10)+ a[o]-'0';
|
||||
if ((n < min[i]) || (n > max[i])) goto err;
|
||||
o++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Missing time zone information. */
|
||||
goto err;
|
||||
}
|
||||
return(o == l);
|
||||
err:
|
||||
return(0);
|
||||
}
|
||||
if (a[o] == 'Z')
|
||||
o++;
|
||||
else if ((a[o] == '+') || (a[o] == '-')) {
|
||||
o++;
|
||||
if (o + 4 > l)
|
||||
goto err;
|
||||
for (i = 7; i < 9; i++) {
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = a[o] - '0';
|
||||
o++;
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = (n * 10) + a[o] - '0';
|
||||
if ((n < min[i]) || (n > max[i]))
|
||||
goto err;
|
||||
o++;
|
||||
}
|
||||
} else {
|
||||
/* Missing time zone information. */
|
||||
goto err;
|
||||
}
|
||||
return (o == l);
|
||||
err:
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ASN1_GENERALIZEDTIME_set_string(ASN1_GENERALIZEDTIME *s, const char *str)
|
||||
{
|
||||
ASN1_GENERALIZEDTIME t;
|
||||
{
|
||||
ASN1_GENERALIZEDTIME t;
|
||||
|
||||
t.type=V_ASN1_GENERALIZEDTIME;
|
||||
t.length=strlen(str);
|
||||
t.data=(unsigned char *)str;
|
||||
if (ASN1_GENERALIZEDTIME_check(&t))
|
||||
{
|
||||
if (s != NULL)
|
||||
{
|
||||
if (!ASN1_STRING_set((ASN1_STRING *)s,
|
||||
(unsigned char *)str,t.length))
|
||||
return 0;
|
||||
s->type=V_ASN1_GENERALIZEDTIME;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
t.type = V_ASN1_GENERALIZEDTIME;
|
||||
t.length = strlen(str);
|
||||
t.data = (unsigned char *)str;
|
||||
if (ASN1_GENERALIZEDTIME_check(&t)) {
|
||||
if (s != NULL) {
|
||||
if (!ASN1_STRING_set((ASN1_STRING *)s,
|
||||
(unsigned char *)str, t.length))
|
||||
return 0;
|
||||
s->type = V_ASN1_GENERALIZEDTIME;
|
||||
}
|
||||
return (1);
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
|
||||
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_set(ASN1_GENERALIZEDTIME *s,
|
||||
time_t t)
|
||||
{
|
||||
return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
|
||||
}
|
||||
time_t t)
|
||||
{
|
||||
return ASN1_GENERALIZEDTIME_adj(s, t, 0, 0);
|
||||
}
|
||||
|
||||
ASN1_GENERALIZEDTIME *ASN1_GENERALIZEDTIME_adj(ASN1_GENERALIZEDTIME *s,
|
||||
time_t t, int offset_day, long offset_sec)
|
||||
{
|
||||
char *p;
|
||||
struct tm *ts;
|
||||
struct tm data;
|
||||
size_t len = 20;
|
||||
time_t t, int offset_day,
|
||||
long offset_sec)
|
||||
{
|
||||
char *p;
|
||||
struct tm *ts;
|
||||
struct tm data;
|
||||
size_t len = 20;
|
||||
|
||||
if (s == NULL)
|
||||
s=M_ASN1_GENERALIZEDTIME_new();
|
||||
if (s == NULL)
|
||||
return(NULL);
|
||||
if (s == NULL)
|
||||
s = M_ASN1_GENERALIZEDTIME_new();
|
||||
if (s == NULL)
|
||||
return (NULL);
|
||||
|
||||
ts=OPENSSL_gmtime(&t, &data);
|
||||
if (ts == NULL)
|
||||
return(NULL);
|
||||
ts = OPENSSL_gmtime(&t, &data);
|
||||
if (ts == NULL)
|
||||
return (NULL);
|
||||
|
||||
if (offset_day || offset_sec)
|
||||
{
|
||||
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
|
||||
return NULL;
|
||||
}
|
||||
if (offset_day || offset_sec) {
|
||||
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
|
||||
return NULL;
|
||||
}
|
||||
|
||||
p=(char *)s->data;
|
||||
if ((p == NULL) || ((size_t)s->length < len))
|
||||
{
|
||||
p=OPENSSL_malloc(len);
|
||||
if (p == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
return(NULL);
|
||||
}
|
||||
if (s->data != NULL)
|
||||
OPENSSL_free(s->data);
|
||||
s->data=(unsigned char *)p;
|
||||
}
|
||||
p = (char *)s->data;
|
||||
if ((p == NULL) || ((size_t)s->length < len)) {
|
||||
p = OPENSSL_malloc(len);
|
||||
if (p == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_GENERALIZEDTIME_ADJ, ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
if (s->data != NULL)
|
||||
OPENSSL_free(s->data);
|
||||
s->data = (unsigned char *)p;
|
||||
}
|
||||
|
||||
BIO_snprintf(p,len,"%04d%02d%02d%02d%02d%02dZ",ts->tm_year + 1900,
|
||||
ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
|
||||
s->length=strlen(p);
|
||||
s->type=V_ASN1_GENERALIZEDTIME;
|
||||
BIO_snprintf(p, len, "%04d%02d%02d%02d%02d%02dZ", ts->tm_year + 1900,
|
||||
ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
|
||||
ts->tm_sec);
|
||||
s->length = strlen(p);
|
||||
s->type = V_ASN1_GENERALIZEDTIME;
|
||||
#ifdef CHARSET_EBCDIC_not
|
||||
ebcdic2ascii(s->data, s->data, s->length);
|
||||
ebcdic2ascii(s->data, s->data, s->length);
|
||||
#endif
|
||||
return(s);
|
||||
}
|
||||
return (s);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -63,101 +63,95 @@
|
||||
|
||||
#ifndef NO_OLD_ASN1
|
||||
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
# ifndef OPENSSL_NO_FP_API
|
||||
int ASN1_i2d_fp(i2d_of_void *i2d, FILE *out, void *x)
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
|
||||
if ((b=BIO_new(BIO_s_file())) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_I2D_FP,ERR_R_BUF_LIB);
|
||||
return(0);
|
||||
}
|
||||
BIO_set_fp(b,out,BIO_NOCLOSE);
|
||||
ret=ASN1_i2d_bio(i2d,b,x);
|
||||
BIO_free(b);
|
||||
return(ret);
|
||||
}
|
||||
#endif
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_I2D_FP, ERR_R_BUF_LIB);
|
||||
return (0);
|
||||
}
|
||||
BIO_set_fp(b, out, BIO_NOCLOSE);
|
||||
ret = ASN1_i2d_bio(i2d, b, x);
|
||||
BIO_free(b);
|
||||
return (ret);
|
||||
}
|
||||
# endif
|
||||
|
||||
int ASN1_i2d_bio(i2d_of_void *i2d, BIO *out, unsigned char *x)
|
||||
{
|
||||
char *b;
|
||||
unsigned char *p;
|
||||
int i,j=0,n,ret=1;
|
||||
{
|
||||
char *b;
|
||||
unsigned char *p;
|
||||
int i, j = 0, n, ret = 1;
|
||||
|
||||
n=i2d(x,NULL);
|
||||
b=(char *)OPENSSL_malloc(n);
|
||||
if (b == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_I2D_BIO,ERR_R_MALLOC_FAILURE);
|
||||
return(0);
|
||||
}
|
||||
n = i2d(x, NULL);
|
||||
b = (char *)OPENSSL_malloc(n);
|
||||
if (b == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_I2D_BIO, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
p=(unsigned char *)b;
|
||||
i2d(x,&p);
|
||||
|
||||
for (;;)
|
||||
{
|
||||
i=BIO_write(out,&(b[j]),n);
|
||||
if (i == n) break;
|
||||
if (i <= 0)
|
||||
{
|
||||
ret=0;
|
||||
break;
|
||||
}
|
||||
j+=i;
|
||||
n-=i;
|
||||
}
|
||||
OPENSSL_free(b);
|
||||
return(ret);
|
||||
}
|
||||
p = (unsigned char *)b;
|
||||
i2d(x, &p);
|
||||
|
||||
for (;;) {
|
||||
i = BIO_write(out, &(b[j]), n);
|
||||
if (i == n)
|
||||
break;
|
||||
if (i <= 0) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
j += i;
|
||||
n -= i;
|
||||
}
|
||||
OPENSSL_free(b);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
int ASN1_item_i2d_fp(const ASN1_ITEM *it, FILE *out, void *x)
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
|
||||
if ((b=BIO_new(BIO_s_file())) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_I2D_FP,ERR_R_BUF_LIB);
|
||||
return(0);
|
||||
}
|
||||
BIO_set_fp(b,out,BIO_NOCLOSE);
|
||||
ret=ASN1_item_i2d_bio(it,b,x);
|
||||
BIO_free(b);
|
||||
return(ret);
|
||||
}
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_I2D_FP, ERR_R_BUF_LIB);
|
||||
return (0);
|
||||
}
|
||||
BIO_set_fp(b, out, BIO_NOCLOSE);
|
||||
ret = ASN1_item_i2d_bio(it, b, x);
|
||||
BIO_free(b);
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
int ASN1_item_i2d_bio(const ASN1_ITEM *it, BIO *out, void *x)
|
||||
{
|
||||
unsigned char *b = NULL;
|
||||
int i,j=0,n,ret=1;
|
||||
{
|
||||
unsigned char *b = NULL;
|
||||
int i, j = 0, n, ret = 1;
|
||||
|
||||
n = ASN1_item_i2d(x, &b, it);
|
||||
if (b == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO,ERR_R_MALLOC_FAILURE);
|
||||
return(0);
|
||||
}
|
||||
n = ASN1_item_i2d(x, &b, it);
|
||||
if (b == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_I2D_BIO, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (;;)
|
||||
{
|
||||
i=BIO_write(out,&(b[j]),n);
|
||||
if (i == n) break;
|
||||
if (i <= 0)
|
||||
{
|
||||
ret=0;
|
||||
break;
|
||||
}
|
||||
j+=i;
|
||||
n-=i;
|
||||
}
|
||||
OPENSSL_free(b);
|
||||
return(ret);
|
||||
}
|
||||
for (;;) {
|
||||
i = BIO_write(out, &(b[j]), n);
|
||||
if (i == n)
|
||||
break;
|
||||
if (i <= 0) {
|
||||
ret = 0;
|
||||
break;
|
||||
}
|
||||
j += i;
|
||||
n -= i;
|
||||
}
|
||||
OPENSSL_free(b);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,45 +62,45 @@
|
||||
#include <openssl/bn.h>
|
||||
|
||||
ASN1_INTEGER *ASN1_INTEGER_dup(const ASN1_INTEGER *x)
|
||||
{ return M_ASN1_INTEGER_dup(x);}
|
||||
{
|
||||
return M_ASN1_INTEGER_dup(x);
|
||||
}
|
||||
|
||||
int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
|
||||
{
|
||||
int neg, ret;
|
||||
/* Compare signs */
|
||||
neg = x->type & V_ASN1_NEG;
|
||||
if (neg != (y->type & V_ASN1_NEG))
|
||||
{
|
||||
if (neg)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
int neg, ret;
|
||||
/* Compare signs */
|
||||
neg = x->type & V_ASN1_NEG;
|
||||
if (neg != (y->type & V_ASN1_NEG)) {
|
||||
if (neg)
|
||||
return -1;
|
||||
else
|
||||
return 1;
|
||||
}
|
||||
|
||||
ret = ASN1_STRING_cmp(x, y);
|
||||
ret = ASN1_STRING_cmp(x, y);
|
||||
|
||||
if (neg)
|
||||
return -ret;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (neg)
|
||||
return -ret;
|
||||
else
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
/*-
|
||||
* This converts an ASN1 INTEGER into its content encoding.
|
||||
* The internal representation is an ASN1_STRING whose data is a big endian
|
||||
* representation of the value, ignoring the sign. The sign is determined by
|
||||
* the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
|
||||
* the type: V_ASN1_INTEGER for positive and V_ASN1_NEG_INTEGER for negative.
|
||||
*
|
||||
* Positive integers are no problem: they are almost the same as the DER
|
||||
* encoding, except if the first byte is >= 0x80 we need to add a zero pad.
|
||||
*
|
||||
* Negative integers are a bit trickier...
|
||||
* The DER representation of negative integers is in 2s complement form.
|
||||
* The internal form is converted by complementing each octet and finally
|
||||
* The internal form is converted by complementing each octet and finally
|
||||
* adding one to the result. This can be done less messily with a little trick.
|
||||
* If the internal form has trailing zeroes then they will become FF by the
|
||||
* complement and 0 by the add one (due to carry) so just copy as many trailing
|
||||
* complement and 0 by the add one (due to carry) so just copy as many trailing
|
||||
* zeros to the destination as there are in the source. The carry will add one
|
||||
* to the last none zero octet: so complement this octet and add one and finally
|
||||
* complement any left over until you get to the start of the string.
|
||||
@ -112,347 +112,353 @@ int ASN1_INTEGER_cmp(const ASN1_INTEGER *x, const ASN1_INTEGER *y)
|
||||
*/
|
||||
|
||||
int i2c_ASN1_INTEGER(ASN1_INTEGER *a, unsigned char **pp)
|
||||
{
|
||||
int pad=0,ret,i,neg;
|
||||
unsigned char *p,*n,pb=0;
|
||||
{
|
||||
int pad = 0, ret, i, neg;
|
||||
unsigned char *p, *n, pb = 0;
|
||||
|
||||
if (a == NULL) return(0);
|
||||
neg=a->type & V_ASN1_NEG;
|
||||
if (a->length == 0)
|
||||
ret=1;
|
||||
else
|
||||
{
|
||||
ret=a->length;
|
||||
i=a->data[0];
|
||||
if (!neg && (i > 127)) {
|
||||
pad=1;
|
||||
pb=0;
|
||||
} else if(neg) {
|
||||
if(i>128) {
|
||||
pad=1;
|
||||
pb=0xFF;
|
||||
} else if(i == 128) {
|
||||
/*
|
||||
* Special case: if any other bytes non zero we pad:
|
||||
* otherwise we don't.
|
||||
*/
|
||||
for(i = 1; i < a->length; i++) if(a->data[i]) {
|
||||
pad=1;
|
||||
pb=0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret+=pad;
|
||||
}
|
||||
if (pp == NULL) return(ret);
|
||||
p= *pp;
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
neg = a->type & V_ASN1_NEG;
|
||||
if (a->length == 0)
|
||||
ret = 1;
|
||||
else {
|
||||
ret = a->length;
|
||||
i = a->data[0];
|
||||
if (ret == 1 && i == 0)
|
||||
neg = 0;
|
||||
if (!neg && (i > 127)) {
|
||||
pad = 1;
|
||||
pb = 0;
|
||||
} else if (neg) {
|
||||
if (i > 128) {
|
||||
pad = 1;
|
||||
pb = 0xFF;
|
||||
} else if (i == 128) {
|
||||
/*
|
||||
* Special case: if any other bytes non zero we pad:
|
||||
* otherwise we don't.
|
||||
*/
|
||||
for (i = 1; i < a->length; i++)
|
||||
if (a->data[i]) {
|
||||
pad = 1;
|
||||
pb = 0xFF;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
ret += pad;
|
||||
}
|
||||
if (pp == NULL)
|
||||
return (ret);
|
||||
p = *pp;
|
||||
|
||||
if (pad) *(p++)=pb;
|
||||
if (a->length == 0) *(p++)=0;
|
||||
else if (!neg) memcpy(p,a->data,(unsigned int)a->length);
|
||||
else {
|
||||
/* Begin at the end of the encoding */
|
||||
n=a->data + a->length - 1;
|
||||
p += a->length - 1;
|
||||
i = a->length;
|
||||
/* Copy zeros to destination as long as source is zero */
|
||||
while(!*n) {
|
||||
*(p--) = 0;
|
||||
n--;
|
||||
i--;
|
||||
}
|
||||
/* Complement and increment next octet */
|
||||
*(p--) = ((*(n--)) ^ 0xff) + 1;
|
||||
i--;
|
||||
/* Complement any octets left */
|
||||
for(;i > 0; i--) *(p--) = *(n--) ^ 0xff;
|
||||
}
|
||||
if (pad)
|
||||
*(p++) = pb;
|
||||
if (a->length == 0)
|
||||
*(p++) = 0;
|
||||
else if (!neg)
|
||||
memcpy(p, a->data, (unsigned int)a->length);
|
||||
else {
|
||||
/* Begin at the end of the encoding */
|
||||
n = a->data + a->length - 1;
|
||||
p += a->length - 1;
|
||||
i = a->length;
|
||||
/* Copy zeros to destination as long as source is zero */
|
||||
while (!*n && i > 1) {
|
||||
*(p--) = 0;
|
||||
n--;
|
||||
i--;
|
||||
}
|
||||
/* Complement and increment next octet */
|
||||
*(p--) = ((*(n--)) ^ 0xff) + 1;
|
||||
i--;
|
||||
/* Complement any octets left */
|
||||
for (; i > 0; i--)
|
||||
*(p--) = *(n--) ^ 0xff;
|
||||
}
|
||||
|
||||
*pp+=ret;
|
||||
return(ret);
|
||||
}
|
||||
*pp += ret;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
/* Convert just ASN1 INTEGER content octets to ASN1_INTEGER structure */
|
||||
|
||||
ASN1_INTEGER *c2i_ASN1_INTEGER(ASN1_INTEGER **a, const unsigned char **pp,
|
||||
long len)
|
||||
{
|
||||
ASN1_INTEGER *ret=NULL;
|
||||
const unsigned char *p, *pend;
|
||||
unsigned char *to,*s;
|
||||
int i;
|
||||
long len)
|
||||
{
|
||||
ASN1_INTEGER *ret = NULL;
|
||||
const unsigned char *p, *pend;
|
||||
unsigned char *to, *s;
|
||||
int i;
|
||||
|
||||
if ((a == NULL) || ((*a) == NULL))
|
||||
{
|
||||
if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
|
||||
ret->type=V_ASN1_INTEGER;
|
||||
}
|
||||
else
|
||||
ret=(*a);
|
||||
if ((a == NULL) || ((*a) == NULL)) {
|
||||
if ((ret = M_ASN1_INTEGER_new()) == NULL)
|
||||
return (NULL);
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
p= *pp;
|
||||
pend = p + len;
|
||||
p = *pp;
|
||||
pend = p + len;
|
||||
|
||||
/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
|
||||
* signifies a missing NULL parameter. */
|
||||
s=(unsigned char *)OPENSSL_malloc((int)len+1);
|
||||
if (s == NULL)
|
||||
{
|
||||
i=ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
to=s;
|
||||
if(!len) {
|
||||
/* Strictly speaking this is an illegal INTEGER but we
|
||||
* tolerate it.
|
||||
*/
|
||||
ret->type=V_ASN1_INTEGER;
|
||||
} else if (*p & 0x80) /* a negative number */
|
||||
{
|
||||
ret->type=V_ASN1_NEG_INTEGER;
|
||||
if ((*p == 0xff) && (len != 1)) {
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
i = len;
|
||||
p += i - 1;
|
||||
to += i - 1;
|
||||
while((!*p) && i) {
|
||||
*(to--) = 0;
|
||||
i--;
|
||||
p--;
|
||||
}
|
||||
/* Special case: if all zeros then the number will be of
|
||||
* the form FF followed by n zero bytes: this corresponds to
|
||||
* 1 followed by n zero bytes. We've already written n zeros
|
||||
* so we just append an extra one and set the first byte to
|
||||
* a 1. This is treated separately because it is the only case
|
||||
* where the number of bytes is larger than len.
|
||||
*/
|
||||
if(!i) {
|
||||
*s = 1;
|
||||
s[len] = 0;
|
||||
len++;
|
||||
} else {
|
||||
*(to--) = (*(p--) ^ 0xff) + 1;
|
||||
i--;
|
||||
for(;i > 0; i--) *(to--) = *(p--) ^ 0xff;
|
||||
}
|
||||
} else {
|
||||
ret->type=V_ASN1_INTEGER;
|
||||
if ((*p == 0) && (len != 1))
|
||||
{
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
memcpy(s,p,(int)len);
|
||||
}
|
||||
/*
|
||||
* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
|
||||
* a missing NULL parameter.
|
||||
*/
|
||||
s = (unsigned char *)OPENSSL_malloc((int)len + 1);
|
||||
if (s == NULL) {
|
||||
i = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
to = s;
|
||||
if (!len) {
|
||||
/*
|
||||
* Strictly speaking this is an illegal INTEGER but we tolerate it.
|
||||
*/
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
} else if (*p & 0x80) { /* a negative number */
|
||||
ret->type = V_ASN1_NEG_INTEGER;
|
||||
if ((*p == 0xff) && (len != 1)) {
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
i = len;
|
||||
p += i - 1;
|
||||
to += i - 1;
|
||||
while ((!*p) && i) {
|
||||
*(to--) = 0;
|
||||
i--;
|
||||
p--;
|
||||
}
|
||||
/*
|
||||
* Special case: if all zeros then the number will be of the form FF
|
||||
* followed by n zero bytes: this corresponds to 1 followed by n zero
|
||||
* bytes. We've already written n zeros so we just append an extra
|
||||
* one and set the first byte to a 1. This is treated separately
|
||||
* because it is the only case where the number of bytes is larger
|
||||
* than len.
|
||||
*/
|
||||
if (!i) {
|
||||
*s = 1;
|
||||
s[len] = 0;
|
||||
len++;
|
||||
} else {
|
||||
*(to--) = (*(p--) ^ 0xff) + 1;
|
||||
i--;
|
||||
for (; i > 0; i--)
|
||||
*(to--) = *(p--) ^ 0xff;
|
||||
}
|
||||
} else {
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
if ((*p == 0) && (len != 1)) {
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
memcpy(s, p, (int)len);
|
||||
}
|
||||
|
||||
if (ret->data != NULL) OPENSSL_free(ret->data);
|
||||
ret->data=s;
|
||||
ret->length=(int)len;
|
||||
if (a != NULL) (*a)=ret;
|
||||
*pp=pend;
|
||||
return(ret);
|
||||
err:
|
||||
ASN1err(ASN1_F_C2I_ASN1_INTEGER,i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_INTEGER_free(ret);
|
||||
return(NULL);
|
||||
}
|
||||
if (ret->data != NULL)
|
||||
OPENSSL_free(ret->data);
|
||||
ret->data = s;
|
||||
ret->length = (int)len;
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = pend;
|
||||
return (ret);
|
||||
err:
|
||||
ASN1err(ASN1_F_C2I_ASN1_INTEGER, i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_INTEGER_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
|
||||
/* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of
|
||||
* ASN1 integers: some broken software can encode a positive INTEGER
|
||||
* with its MSB set as negative (it doesn't add a padding zero).
|
||||
/*
|
||||
* This is a version of d2i_ASN1_INTEGER that ignores the sign bit of ASN1
|
||||
* integers: some broken software can encode a positive INTEGER with its MSB
|
||||
* set as negative (it doesn't add a padding zero).
|
||||
*/
|
||||
|
||||
ASN1_INTEGER *d2i_ASN1_UINTEGER(ASN1_INTEGER **a, const unsigned char **pp,
|
||||
long length)
|
||||
{
|
||||
ASN1_INTEGER *ret=NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *s;
|
||||
long len;
|
||||
int inf,tag,xclass;
|
||||
int i;
|
||||
long length)
|
||||
{
|
||||
ASN1_INTEGER *ret = NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *s;
|
||||
long len;
|
||||
int inf, tag, xclass;
|
||||
int i;
|
||||
|
||||
if ((a == NULL) || ((*a) == NULL))
|
||||
{
|
||||
if ((ret=M_ASN1_INTEGER_new()) == NULL) return(NULL);
|
||||
ret->type=V_ASN1_INTEGER;
|
||||
}
|
||||
else
|
||||
ret=(*a);
|
||||
if ((a == NULL) || ((*a) == NULL)) {
|
||||
if ((ret = M_ASN1_INTEGER_new()) == NULL)
|
||||
return (NULL);
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
p= *pp;
|
||||
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
|
||||
if (inf & 0x80)
|
||||
{
|
||||
i=ASN1_R_BAD_OBJECT_HEADER;
|
||||
goto err;
|
||||
}
|
||||
p = *pp;
|
||||
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
|
||||
if (inf & 0x80) {
|
||||
i = ASN1_R_BAD_OBJECT_HEADER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tag != V_ASN1_INTEGER)
|
||||
{
|
||||
i=ASN1_R_EXPECTING_AN_INTEGER;
|
||||
goto err;
|
||||
}
|
||||
if (tag != V_ASN1_INTEGER) {
|
||||
i = ASN1_R_EXPECTING_AN_INTEGER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it
|
||||
* signifies a missing NULL parameter. */
|
||||
s=(unsigned char *)OPENSSL_malloc((int)len+1);
|
||||
if (s == NULL)
|
||||
{
|
||||
i=ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
ret->type=V_ASN1_INTEGER;
|
||||
if(len) {
|
||||
if ((*p == 0) && (len != 1))
|
||||
{
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
memcpy(s,p,(int)len);
|
||||
p+=len;
|
||||
}
|
||||
/*
|
||||
* We must OPENSSL_malloc stuff, even for 0 bytes otherwise it signifies
|
||||
* a missing NULL parameter.
|
||||
*/
|
||||
s = (unsigned char *)OPENSSL_malloc((int)len + 1);
|
||||
if (s == NULL) {
|
||||
i = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
if (len) {
|
||||
if ((*p == 0) && (len != 1)) {
|
||||
p++;
|
||||
len--;
|
||||
}
|
||||
memcpy(s, p, (int)len);
|
||||
p += len;
|
||||
}
|
||||
|
||||
if (ret->data != NULL) OPENSSL_free(ret->data);
|
||||
ret->data=s;
|
||||
ret->length=(int)len;
|
||||
if (a != NULL) (*a)=ret;
|
||||
*pp=p;
|
||||
return(ret);
|
||||
err:
|
||||
ASN1err(ASN1_F_D2I_ASN1_UINTEGER,i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_INTEGER_free(ret);
|
||||
return(NULL);
|
||||
}
|
||||
if (ret->data != NULL)
|
||||
OPENSSL_free(ret->data);
|
||||
ret->data = s;
|
||||
ret->length = (int)len;
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = p;
|
||||
return (ret);
|
||||
err:
|
||||
ASN1err(ASN1_F_D2I_ASN1_UINTEGER, i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_INTEGER_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
int ASN1_INTEGER_set(ASN1_INTEGER *a, long v)
|
||||
{
|
||||
int j,k;
|
||||
unsigned int i;
|
||||
unsigned char buf[sizeof(long)+1];
|
||||
long d;
|
||||
{
|
||||
int j, k;
|
||||
unsigned int i;
|
||||
unsigned char buf[sizeof(long) + 1];
|
||||
long d;
|
||||
|
||||
a->type=V_ASN1_INTEGER;
|
||||
if (a->length < (int)(sizeof(long)+1))
|
||||
{
|
||||
if (a->data != NULL)
|
||||
OPENSSL_free(a->data);
|
||||
if ((a->data=(unsigned char *)OPENSSL_malloc(sizeof(long)+1)) != NULL)
|
||||
memset((char *)a->data,0,sizeof(long)+1);
|
||||
}
|
||||
if (a->data == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_INTEGER_SET,ERR_R_MALLOC_FAILURE);
|
||||
return(0);
|
||||
}
|
||||
d=v;
|
||||
if (d < 0)
|
||||
{
|
||||
d= -d;
|
||||
a->type=V_ASN1_NEG_INTEGER;
|
||||
}
|
||||
a->type = V_ASN1_INTEGER;
|
||||
if (a->length < (int)(sizeof(long) + 1)) {
|
||||
if (a->data != NULL)
|
||||
OPENSSL_free(a->data);
|
||||
if ((a->data =
|
||||
(unsigned char *)OPENSSL_malloc(sizeof(long) + 1)) != NULL)
|
||||
memset((char *)a->data, 0, sizeof(long) + 1);
|
||||
}
|
||||
if (a->data == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_INTEGER_SET, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
d = v;
|
||||
if (d < 0) {
|
||||
d = -d;
|
||||
a->type = V_ASN1_NEG_INTEGER;
|
||||
}
|
||||
|
||||
for (i=0; i<sizeof(long); i++)
|
||||
{
|
||||
if (d == 0) break;
|
||||
buf[i]=(int)d&0xff;
|
||||
d>>=8;
|
||||
}
|
||||
j=0;
|
||||
for (k=i-1; k >=0; k--)
|
||||
a->data[j++]=buf[k];
|
||||
a->length=j;
|
||||
return(1);
|
||||
}
|
||||
for (i = 0; i < sizeof(long); i++) {
|
||||
if (d == 0)
|
||||
break;
|
||||
buf[i] = (int)d & 0xff;
|
||||
d >>= 8;
|
||||
}
|
||||
j = 0;
|
||||
for (k = i - 1; k >= 0; k--)
|
||||
a->data[j++] = buf[k];
|
||||
a->length = j;
|
||||
return (1);
|
||||
}
|
||||
|
||||
long ASN1_INTEGER_get(const ASN1_INTEGER *a)
|
||||
{
|
||||
int neg=0,i;
|
||||
long r=0;
|
||||
{
|
||||
int neg = 0, i;
|
||||
long r = 0;
|
||||
|
||||
if (a == NULL) return(0L);
|
||||
i=a->type;
|
||||
if (i == V_ASN1_NEG_INTEGER)
|
||||
neg=1;
|
||||
else if (i != V_ASN1_INTEGER)
|
||||
return -1;
|
||||
|
||||
if (a->length > (int)sizeof(long))
|
||||
{
|
||||
/* hmm... a bit ugly, return all ones */
|
||||
return -1;
|
||||
}
|
||||
if (a->data == NULL)
|
||||
return 0;
|
||||
if (a == NULL)
|
||||
return (0L);
|
||||
i = a->type;
|
||||
if (i == V_ASN1_NEG_INTEGER)
|
||||
neg = 1;
|
||||
else if (i != V_ASN1_INTEGER)
|
||||
return -1;
|
||||
|
||||
for (i=0; i<a->length; i++)
|
||||
{
|
||||
r<<=8;
|
||||
r|=(unsigned char)a->data[i];
|
||||
}
|
||||
if (neg) r= -r;
|
||||
return(r);
|
||||
}
|
||||
if (a->length > (int)sizeof(long)) {
|
||||
/* hmm... a bit ugly, return all ones */
|
||||
return -1;
|
||||
}
|
||||
if (a->data == NULL)
|
||||
return 0;
|
||||
|
||||
for (i = 0; i < a->length; i++) {
|
||||
r <<= 8;
|
||||
r |= (unsigned char)a->data[i];
|
||||
}
|
||||
if (neg)
|
||||
r = -r;
|
||||
return (r);
|
||||
}
|
||||
|
||||
ASN1_INTEGER *BN_to_ASN1_INTEGER(const BIGNUM *bn, ASN1_INTEGER *ai)
|
||||
{
|
||||
ASN1_INTEGER *ret;
|
||||
int len,j;
|
||||
{
|
||||
ASN1_INTEGER *ret;
|
||||
int len, j;
|
||||
|
||||
if (ai == NULL)
|
||||
ret=M_ASN1_INTEGER_new();
|
||||
else
|
||||
ret=ai;
|
||||
if (ret == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_NESTED_ASN1_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_negative(bn))
|
||||
ret->type = V_ASN1_NEG_INTEGER;
|
||||
else ret->type=V_ASN1_INTEGER;
|
||||
j=BN_num_bits(bn);
|
||||
len=((j == 0)?0:((j/8)+1));
|
||||
if (ret->length < len+4)
|
||||
{
|
||||
unsigned char *new_data=OPENSSL_realloc(ret->data, len+4);
|
||||
if (!new_data)
|
||||
{
|
||||
ASN1err(ASN1_F_BN_TO_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
ret->data=new_data;
|
||||
}
|
||||
ret->length=BN_bn2bin(bn,ret->data);
|
||||
/* Correct zero case */
|
||||
if(!ret->length)
|
||||
{
|
||||
ret->data[0] = 0;
|
||||
ret->length = 1;
|
||||
}
|
||||
return(ret);
|
||||
err:
|
||||
if (ret != ai) M_ASN1_INTEGER_free(ret);
|
||||
return(NULL);
|
||||
}
|
||||
if (ai == NULL)
|
||||
ret = M_ASN1_INTEGER_new();
|
||||
else
|
||||
ret = ai;
|
||||
if (ret == NULL) {
|
||||
ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_NESTED_ASN1_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (BN_is_negative(bn) && !BN_is_zero(bn))
|
||||
ret->type = V_ASN1_NEG_INTEGER;
|
||||
else
|
||||
ret->type = V_ASN1_INTEGER;
|
||||
j = BN_num_bits(bn);
|
||||
len = ((j == 0) ? 0 : ((j / 8) + 1));
|
||||
if (ret->length < len + 4) {
|
||||
unsigned char *new_data = OPENSSL_realloc(ret->data, len + 4);
|
||||
if (!new_data) {
|
||||
ASN1err(ASN1_F_BN_TO_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
ret->data = new_data;
|
||||
}
|
||||
ret->length = BN_bn2bin(bn, ret->data);
|
||||
/* Correct zero case */
|
||||
if (!ret->length) {
|
||||
ret->data[0] = 0;
|
||||
ret->length = 1;
|
||||
}
|
||||
return (ret);
|
||||
err:
|
||||
if (ret != ai)
|
||||
M_ASN1_INTEGER_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
BIGNUM *ASN1_INTEGER_to_BN(const ASN1_INTEGER *ai, BIGNUM *bn)
|
||||
{
|
||||
BIGNUM *ret;
|
||||
{
|
||||
BIGNUM *ret;
|
||||
|
||||
if ((ret=BN_bin2bn(ai->data,ai->length,bn)) == NULL)
|
||||
ASN1err(ASN1_F_ASN1_INTEGER_TO_BN,ASN1_R_BN_LIB);
|
||||
else if(ai->type == V_ASN1_NEG_INTEGER)
|
||||
BN_set_negative(ret, 1);
|
||||
return(ret);
|
||||
}
|
||||
if ((ret = BN_bin2bn(ai->data, ai->length, bn)) == NULL)
|
||||
ASN1err(ASN1_F_ASN1_INTEGER_TO_BN, ASN1_R_BN_LIB);
|
||||
else if (ai->type == V_ASN1_NEG_INTEGER)
|
||||
BN_set_negative(ret, 1);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
IMPLEMENT_STACK_OF(ASN1_INTEGER)
|
||||
|
||||
IMPLEMENT_ASN1_SET_OF(ASN1_INTEGER)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* a_mbstr.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -62,7 +63,8 @@
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
static int traverse_string(const unsigned char *p, int len, int inform,
|
||||
int (*rfunc)(unsigned long value, void *in), void *arg);
|
||||
int (*rfunc) (unsigned long value, void *in),
|
||||
void *arg);
|
||||
static int in_utf8(unsigned long value, void *arg);
|
||||
static int out_utf8(unsigned long value, void *arg);
|
||||
static int type_str(unsigned long value, void *arg);
|
||||
@ -72,212 +74,221 @@ static int cpy_univ(unsigned long value, void *arg);
|
||||
static int cpy_utf8(unsigned long value, void *arg);
|
||||
static int is_printable(unsigned long value);
|
||||
|
||||
/* These functions take a string in UTF8, ASCII or multibyte form and
|
||||
* a mask of permissible ASN1 string types. It then works out the minimal
|
||||
* type (using the order Printable < IA5 < T61 < BMP < Universal < UTF8)
|
||||
* and creates a string of the correct type with the supplied data.
|
||||
* Yes this is horrible: it has to be :-(
|
||||
* The 'ncopy' form checks minimum and maximum size limits too.
|
||||
/*
|
||||
* These functions take a string in UTF8, ASCII or multibyte form and a mask
|
||||
* of permissible ASN1 string types. It then works out the minimal type
|
||||
* (using the order Printable < IA5 < T61 < BMP < Universal < UTF8) and
|
||||
* creates a string of the correct type with the supplied data. Yes this is
|
||||
* horrible: it has to be :-( The 'ncopy' form checks minimum and maximum
|
||||
* size limits too.
|
||||
*/
|
||||
|
||||
int ASN1_mbstring_copy(ASN1_STRING **out, const unsigned char *in, int len,
|
||||
int inform, unsigned long mask)
|
||||
int inform, unsigned long mask)
|
||||
{
|
||||
return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
|
||||
return ASN1_mbstring_ncopy(out, in, len, inform, mask, 0, 0);
|
||||
}
|
||||
|
||||
int ASN1_mbstring_ncopy(ASN1_STRING **out, const unsigned char *in, int len,
|
||||
int inform, unsigned long mask,
|
||||
long minsize, long maxsize)
|
||||
int inform, unsigned long mask,
|
||||
long minsize, long maxsize)
|
||||
{
|
||||
int str_type;
|
||||
int ret;
|
||||
char free_out;
|
||||
int outform, outlen = 0;
|
||||
ASN1_STRING *dest;
|
||||
unsigned char *p;
|
||||
int nchar;
|
||||
char strbuf[32];
|
||||
int (*cpyfunc)(unsigned long,void *) = NULL;
|
||||
if(len == -1) len = strlen((const char *)in);
|
||||
if(!mask) mask = DIRSTRING_TYPE;
|
||||
int str_type;
|
||||
int ret;
|
||||
char free_out;
|
||||
int outform, outlen = 0;
|
||||
ASN1_STRING *dest;
|
||||
unsigned char *p;
|
||||
int nchar;
|
||||
char strbuf[32];
|
||||
int (*cpyfunc) (unsigned long, void *) = NULL;
|
||||
if (len == -1)
|
||||
len = strlen((const char *)in);
|
||||
if (!mask)
|
||||
mask = DIRSTRING_TYPE;
|
||||
|
||||
/* First do a string check and work out the number of characters */
|
||||
switch(inform) {
|
||||
/* First do a string check and work out the number of characters */
|
||||
switch (inform) {
|
||||
|
||||
case MBSTRING_BMP:
|
||||
if(len & 1) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
|
||||
ASN1_R_INVALID_BMPSTRING_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
nchar = len >> 1;
|
||||
break;
|
||||
case MBSTRING_BMP:
|
||||
if (len & 1) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
|
||||
ASN1_R_INVALID_BMPSTRING_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
nchar = len >> 1;
|
||||
break;
|
||||
|
||||
case MBSTRING_UNIV:
|
||||
if(len & 3) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
|
||||
ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
nchar = len >> 2;
|
||||
break;
|
||||
case MBSTRING_UNIV:
|
||||
if (len & 3) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
|
||||
ASN1_R_INVALID_UNIVERSALSTRING_LENGTH);
|
||||
return -1;
|
||||
}
|
||||
nchar = len >> 2;
|
||||
break;
|
||||
|
||||
case MBSTRING_UTF8:
|
||||
nchar = 0;
|
||||
/* This counts the characters and does utf8 syntax checking */
|
||||
ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
|
||||
if(ret < 0) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
|
||||
ASN1_R_INVALID_UTF8STRING);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
case MBSTRING_UTF8:
|
||||
nchar = 0;
|
||||
/* This counts the characters and does utf8 syntax checking */
|
||||
ret = traverse_string(in, len, MBSTRING_UTF8, in_utf8, &nchar);
|
||||
if (ret < 0) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_INVALID_UTF8STRING);
|
||||
return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case MBSTRING_ASC:
|
||||
nchar = len;
|
||||
break;
|
||||
case MBSTRING_ASC:
|
||||
nchar = len;
|
||||
break;
|
||||
|
||||
default:
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
|
||||
return -1;
|
||||
}
|
||||
default:
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_UNKNOWN_FORMAT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((minsize > 0) && (nchar < minsize)) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
|
||||
BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
|
||||
ERR_add_error_data(2, "minsize=", strbuf);
|
||||
return -1;
|
||||
}
|
||||
if ((minsize > 0) && (nchar < minsize)) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_SHORT);
|
||||
BIO_snprintf(strbuf, sizeof strbuf, "%ld", minsize);
|
||||
ERR_add_error_data(2, "minsize=", strbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if((maxsize > 0) && (nchar > maxsize)) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
|
||||
BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
|
||||
ERR_add_error_data(2, "maxsize=", strbuf);
|
||||
return -1;
|
||||
}
|
||||
if ((maxsize > 0) && (nchar > maxsize)) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_STRING_TOO_LONG);
|
||||
BIO_snprintf(strbuf, sizeof strbuf, "%ld", maxsize);
|
||||
ERR_add_error_data(2, "maxsize=", strbuf);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Now work out minimal type (if any) */
|
||||
if(traverse_string(in, len, inform, type_str, &mask) < 0) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
|
||||
return -1;
|
||||
}
|
||||
/* Now work out minimal type (if any) */
|
||||
if (traverse_string(in, len, inform, type_str, &mask) < 0) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ASN1_R_ILLEGAL_CHARACTERS);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Now work out output format and string type */
|
||||
outform = MBSTRING_ASC;
|
||||
if (mask & B_ASN1_PRINTABLESTRING)
|
||||
str_type = V_ASN1_PRINTABLESTRING;
|
||||
else if (mask & B_ASN1_IA5STRING)
|
||||
str_type = V_ASN1_IA5STRING;
|
||||
else if (mask & B_ASN1_T61STRING)
|
||||
str_type = V_ASN1_T61STRING;
|
||||
else if (mask & B_ASN1_BMPSTRING) {
|
||||
str_type = V_ASN1_BMPSTRING;
|
||||
outform = MBSTRING_BMP;
|
||||
} else if (mask & B_ASN1_UNIVERSALSTRING) {
|
||||
str_type = V_ASN1_UNIVERSALSTRING;
|
||||
outform = MBSTRING_UNIV;
|
||||
} else {
|
||||
str_type = V_ASN1_UTF8STRING;
|
||||
outform = MBSTRING_UTF8;
|
||||
}
|
||||
if (!out)
|
||||
return str_type;
|
||||
if (*out) {
|
||||
free_out = 0;
|
||||
dest = *out;
|
||||
if (dest->data) {
|
||||
dest->length = 0;
|
||||
OPENSSL_free(dest->data);
|
||||
dest->data = NULL;
|
||||
}
|
||||
dest->type = str_type;
|
||||
} else {
|
||||
free_out = 1;
|
||||
dest = ASN1_STRING_type_new(str_type);
|
||||
if (!dest) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
*out = dest;
|
||||
}
|
||||
/* If both the same type just copy across */
|
||||
if (inform == outform) {
|
||||
if (!ASN1_STRING_set(dest, in, len)) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
return str_type;
|
||||
}
|
||||
|
||||
/* Now work out output format and string type */
|
||||
outform = MBSTRING_ASC;
|
||||
if(mask & B_ASN1_PRINTABLESTRING) str_type = V_ASN1_PRINTABLESTRING;
|
||||
else if(mask & B_ASN1_IA5STRING) str_type = V_ASN1_IA5STRING;
|
||||
else if(mask & B_ASN1_T61STRING) str_type = V_ASN1_T61STRING;
|
||||
else if(mask & B_ASN1_BMPSTRING) {
|
||||
str_type = V_ASN1_BMPSTRING;
|
||||
outform = MBSTRING_BMP;
|
||||
} else if(mask & B_ASN1_UNIVERSALSTRING) {
|
||||
str_type = V_ASN1_UNIVERSALSTRING;
|
||||
outform = MBSTRING_UNIV;
|
||||
} else {
|
||||
str_type = V_ASN1_UTF8STRING;
|
||||
outform = MBSTRING_UTF8;
|
||||
}
|
||||
if(!out) return str_type;
|
||||
if(*out) {
|
||||
free_out = 0;
|
||||
dest = *out;
|
||||
if(dest->data) {
|
||||
dest->length = 0;
|
||||
OPENSSL_free(dest->data);
|
||||
dest->data = NULL;
|
||||
}
|
||||
dest->type = str_type;
|
||||
} else {
|
||||
free_out = 1;
|
||||
dest = ASN1_STRING_type_new(str_type);
|
||||
if(!dest) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
*out = dest;
|
||||
}
|
||||
/* If both the same type just copy across */
|
||||
if(inform == outform) {
|
||||
if(!ASN1_STRING_set(dest, in, len)) {
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
return str_type;
|
||||
}
|
||||
/* Work out how much space the destination will need */
|
||||
switch (outform) {
|
||||
case MBSTRING_ASC:
|
||||
outlen = nchar;
|
||||
cpyfunc = cpy_asc;
|
||||
break;
|
||||
|
||||
/* Work out how much space the destination will need */
|
||||
switch(outform) {
|
||||
case MBSTRING_ASC:
|
||||
outlen = nchar;
|
||||
cpyfunc = cpy_asc;
|
||||
break;
|
||||
case MBSTRING_BMP:
|
||||
outlen = nchar << 1;
|
||||
cpyfunc = cpy_bmp;
|
||||
break;
|
||||
|
||||
case MBSTRING_BMP:
|
||||
outlen = nchar << 1;
|
||||
cpyfunc = cpy_bmp;
|
||||
break;
|
||||
case MBSTRING_UNIV:
|
||||
outlen = nchar << 2;
|
||||
cpyfunc = cpy_univ;
|
||||
break;
|
||||
|
||||
case MBSTRING_UNIV:
|
||||
outlen = nchar << 2;
|
||||
cpyfunc = cpy_univ;
|
||||
break;
|
||||
|
||||
case MBSTRING_UTF8:
|
||||
outlen = 0;
|
||||
traverse_string(in, len, inform, out_utf8, &outlen);
|
||||
cpyfunc = cpy_utf8;
|
||||
break;
|
||||
}
|
||||
if(!(p = OPENSSL_malloc(outlen + 1))) {
|
||||
if(free_out) ASN1_STRING_free(dest);
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY,ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
dest->length = outlen;
|
||||
dest->data = p;
|
||||
p[outlen] = 0;
|
||||
traverse_string(in, len, inform, cpyfunc, &p);
|
||||
return str_type;
|
||||
case MBSTRING_UTF8:
|
||||
outlen = 0;
|
||||
traverse_string(in, len, inform, out_utf8, &outlen);
|
||||
cpyfunc = cpy_utf8;
|
||||
break;
|
||||
}
|
||||
if (!(p = OPENSSL_malloc(outlen + 1))) {
|
||||
if (free_out)
|
||||
ASN1_STRING_free(dest);
|
||||
ASN1err(ASN1_F_ASN1_MBSTRING_NCOPY, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
dest->length = outlen;
|
||||
dest->data = p;
|
||||
p[outlen] = 0;
|
||||
traverse_string(in, len, inform, cpyfunc, &p);
|
||||
return str_type;
|
||||
}
|
||||
|
||||
/* This function traverses a string and passes the value of each character
|
||||
* to an optional function along with a void * argument.
|
||||
/*
|
||||
* This function traverses a string and passes the value of each character to
|
||||
* an optional function along with a void * argument.
|
||||
*/
|
||||
|
||||
static int traverse_string(const unsigned char *p, int len, int inform,
|
||||
int (*rfunc)(unsigned long value, void *in), void *arg)
|
||||
int (*rfunc) (unsigned long value, void *in),
|
||||
void *arg)
|
||||
{
|
||||
unsigned long value;
|
||||
int ret;
|
||||
while(len) {
|
||||
if(inform == MBSTRING_ASC) {
|
||||
value = *p++;
|
||||
len--;
|
||||
} else if(inform == MBSTRING_BMP) {
|
||||
value = *p++ << 8;
|
||||
value |= *p++;
|
||||
len -= 2;
|
||||
} else if(inform == MBSTRING_UNIV) {
|
||||
value = ((unsigned long)*p++) << 24;
|
||||
value |= ((unsigned long)*p++) << 16;
|
||||
value |= *p++ << 8;
|
||||
value |= *p++;
|
||||
len -= 4;
|
||||
} else {
|
||||
ret = UTF8_getc(p, len, &value);
|
||||
if(ret < 0) return -1;
|
||||
len -= ret;
|
||||
p += ret;
|
||||
}
|
||||
if(rfunc) {
|
||||
ret = rfunc(value, arg);
|
||||
if(ret <= 0) return ret;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
unsigned long value;
|
||||
int ret;
|
||||
while (len) {
|
||||
if (inform == MBSTRING_ASC) {
|
||||
value = *p++;
|
||||
len--;
|
||||
} else if (inform == MBSTRING_BMP) {
|
||||
value = *p++ << 8;
|
||||
value |= *p++;
|
||||
len -= 2;
|
||||
} else if (inform == MBSTRING_UNIV) {
|
||||
value = ((unsigned long)*p++) << 24;
|
||||
value |= ((unsigned long)*p++) << 16;
|
||||
value |= *p++ << 8;
|
||||
value |= *p++;
|
||||
len -= 4;
|
||||
} else {
|
||||
ret = UTF8_getc(p, len, &value);
|
||||
if (ret < 0)
|
||||
return -1;
|
||||
len -= ret;
|
||||
p += ret;
|
||||
}
|
||||
if (rfunc) {
|
||||
ret = rfunc(value, arg);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Various utility functions for traverse_string */
|
||||
@ -286,115 +297,127 @@ static int traverse_string(const unsigned char *p, int len, int inform,
|
||||
|
||||
static int in_utf8(unsigned long value, void *arg)
|
||||
{
|
||||
int *nchar;
|
||||
nchar = arg;
|
||||
(*nchar)++;
|
||||
return 1;
|
||||
int *nchar;
|
||||
nchar = arg;
|
||||
(*nchar)++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Determine size of output as a UTF8 String */
|
||||
|
||||
static int out_utf8(unsigned long value, void *arg)
|
||||
{
|
||||
int *outlen;
|
||||
outlen = arg;
|
||||
*outlen += UTF8_putc(NULL, -1, value);
|
||||
return 1;
|
||||
int *outlen;
|
||||
outlen = arg;
|
||||
*outlen += UTF8_putc(NULL, -1, value);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Determine the "type" of a string: check each character against a
|
||||
* supplied "mask".
|
||||
/*
|
||||
* Determine the "type" of a string: check each character against a supplied
|
||||
* "mask".
|
||||
*/
|
||||
|
||||
static int type_str(unsigned long value, void *arg)
|
||||
{
|
||||
unsigned long types;
|
||||
types = *((unsigned long *)arg);
|
||||
if((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
|
||||
types &= ~B_ASN1_PRINTABLESTRING;
|
||||
if((types & B_ASN1_IA5STRING) && (value > 127))
|
||||
types &= ~B_ASN1_IA5STRING;
|
||||
if((types & B_ASN1_T61STRING) && (value > 0xff))
|
||||
types &= ~B_ASN1_T61STRING;
|
||||
if((types & B_ASN1_BMPSTRING) && (value > 0xffff))
|
||||
types &= ~B_ASN1_BMPSTRING;
|
||||
if(!types) return -1;
|
||||
*((unsigned long *)arg) = types;
|
||||
return 1;
|
||||
unsigned long types;
|
||||
types = *((unsigned long *)arg);
|
||||
if ((types & B_ASN1_PRINTABLESTRING) && !is_printable(value))
|
||||
types &= ~B_ASN1_PRINTABLESTRING;
|
||||
if ((types & B_ASN1_IA5STRING) && (value > 127))
|
||||
types &= ~B_ASN1_IA5STRING;
|
||||
if ((types & B_ASN1_T61STRING) && (value > 0xff))
|
||||
types &= ~B_ASN1_T61STRING;
|
||||
if ((types & B_ASN1_BMPSTRING) && (value > 0xffff))
|
||||
types &= ~B_ASN1_BMPSTRING;
|
||||
if (!types)
|
||||
return -1;
|
||||
*((unsigned long *)arg) = types;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Copy one byte per character ASCII like strings */
|
||||
|
||||
static int cpy_asc(unsigned long value, void *arg)
|
||||
{
|
||||
unsigned char **p, *q;
|
||||
p = arg;
|
||||
q = *p;
|
||||
*q = (unsigned char) value;
|
||||
(*p)++;
|
||||
return 1;
|
||||
unsigned char **p, *q;
|
||||
p = arg;
|
||||
q = *p;
|
||||
*q = (unsigned char)value;
|
||||
(*p)++;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Copy two byte per character BMPStrings */
|
||||
|
||||
static int cpy_bmp(unsigned long value, void *arg)
|
||||
{
|
||||
unsigned char **p, *q;
|
||||
p = arg;
|
||||
q = *p;
|
||||
*q++ = (unsigned char) ((value >> 8) & 0xff);
|
||||
*q = (unsigned char) (value & 0xff);
|
||||
*p += 2;
|
||||
return 1;
|
||||
unsigned char **p, *q;
|
||||
p = arg;
|
||||
q = *p;
|
||||
*q++ = (unsigned char)((value >> 8) & 0xff);
|
||||
*q = (unsigned char)(value & 0xff);
|
||||
*p += 2;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Copy four byte per character UniversalStrings */
|
||||
|
||||
static int cpy_univ(unsigned long value, void *arg)
|
||||
{
|
||||
unsigned char **p, *q;
|
||||
p = arg;
|
||||
q = *p;
|
||||
*q++ = (unsigned char) ((value >> 24) & 0xff);
|
||||
*q++ = (unsigned char) ((value >> 16) & 0xff);
|
||||
*q++ = (unsigned char) ((value >> 8) & 0xff);
|
||||
*q = (unsigned char) (value & 0xff);
|
||||
*p += 4;
|
||||
return 1;
|
||||
unsigned char **p, *q;
|
||||
p = arg;
|
||||
q = *p;
|
||||
*q++ = (unsigned char)((value >> 24) & 0xff);
|
||||
*q++ = (unsigned char)((value >> 16) & 0xff);
|
||||
*q++ = (unsigned char)((value >> 8) & 0xff);
|
||||
*q = (unsigned char)(value & 0xff);
|
||||
*p += 4;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Copy to a UTF8String */
|
||||
|
||||
static int cpy_utf8(unsigned long value, void *arg)
|
||||
{
|
||||
unsigned char **p;
|
||||
int ret;
|
||||
p = arg;
|
||||
/* We already know there is enough room so pass 0xff as the length */
|
||||
ret = UTF8_putc(*p, 0xff, value);
|
||||
*p += ret;
|
||||
return 1;
|
||||
unsigned char **p;
|
||||
int ret;
|
||||
p = arg;
|
||||
/* We already know there is enough room so pass 0xff as the length */
|
||||
ret = UTF8_putc(*p, 0xff, value);
|
||||
*p += ret;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Return 1 if the character is permitted in a PrintableString */
|
||||
static int is_printable(unsigned long value)
|
||||
{
|
||||
int ch;
|
||||
if(value > 0x7f) return 0;
|
||||
ch = (int) value;
|
||||
/* Note: we can't use 'isalnum' because certain accented
|
||||
* characters may count as alphanumeric in some environments.
|
||||
*/
|
||||
int ch;
|
||||
if (value > 0x7f)
|
||||
return 0;
|
||||
ch = (int)value;
|
||||
/*
|
||||
* Note: we can't use 'isalnum' because certain accented characters may
|
||||
* count as alphanumeric in some environments.
|
||||
*/
|
||||
#ifndef CHARSET_EBCDIC
|
||||
if((ch >= 'a') && (ch <= 'z')) return 1;
|
||||
if((ch >= 'A') && (ch <= 'Z')) return 1;
|
||||
if((ch >= '0') && (ch <= '9')) return 1;
|
||||
if ((ch == ' ') || strchr("'()+,-./:=?", ch)) return 1;
|
||||
#else /*CHARSET_EBCDIC*/
|
||||
if((ch >= os_toascii['a']) && (ch <= os_toascii['z'])) return 1;
|
||||
if((ch >= os_toascii['A']) && (ch <= os_toascii['Z'])) return 1;
|
||||
if((ch >= os_toascii['0']) && (ch <= os_toascii['9'])) return 1;
|
||||
if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch])) return 1;
|
||||
#endif /*CHARSET_EBCDIC*/
|
||||
return 0;
|
||||
if ((ch >= 'a') && (ch <= 'z'))
|
||||
return 1;
|
||||
if ((ch >= 'A') && (ch <= 'Z'))
|
||||
return 1;
|
||||
if ((ch >= '0') && (ch <= '9'))
|
||||
return 1;
|
||||
if ((ch == ' ') || strchr("'()+,-./:=?", ch))
|
||||
return 1;
|
||||
#else /* CHARSET_EBCDIC */
|
||||
if ((ch >= os_toascii['a']) && (ch <= os_toascii['z']))
|
||||
return 1;
|
||||
if ((ch >= os_toascii['A']) && (ch <= os_toascii['Z']))
|
||||
return 1;
|
||||
if ((ch >= os_toascii['0']) && (ch <= os_toascii['9']))
|
||||
return 1;
|
||||
if ((ch == os_toascii[' ']) || strchr("'()+,-./:=?", os_toebcdic[ch]))
|
||||
return 1;
|
||||
#endif /* CHARSET_EBCDIC */
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -65,339 +65,338 @@
|
||||
#include <openssl/bn.h>
|
||||
|
||||
int i2d_ASN1_OBJECT(ASN1_OBJECT *a, unsigned char **pp)
|
||||
{
|
||||
unsigned char *p;
|
||||
int objsize;
|
||||
{
|
||||
unsigned char *p;
|
||||
int objsize;
|
||||
|
||||
if ((a == NULL) || (a->data == NULL)) return(0);
|
||||
if ((a == NULL) || (a->data == NULL))
|
||||
return (0);
|
||||
|
||||
objsize = ASN1_object_size(0,a->length,V_ASN1_OBJECT);
|
||||
if (pp == NULL) return objsize;
|
||||
objsize = ASN1_object_size(0, a->length, V_ASN1_OBJECT);
|
||||
if (pp == NULL)
|
||||
return objsize;
|
||||
|
||||
p= *pp;
|
||||
ASN1_put_object(&p,0,a->length,V_ASN1_OBJECT,V_ASN1_UNIVERSAL);
|
||||
memcpy(p,a->data,a->length);
|
||||
p+=a->length;
|
||||
p = *pp;
|
||||
ASN1_put_object(&p, 0, a->length, V_ASN1_OBJECT, V_ASN1_UNIVERSAL);
|
||||
memcpy(p, a->data, a->length);
|
||||
p += a->length;
|
||||
|
||||
*pp=p;
|
||||
return(objsize);
|
||||
}
|
||||
*pp = p;
|
||||
return (objsize);
|
||||
}
|
||||
|
||||
int a2d_ASN1_OBJECT(unsigned char *out, int olen, const char *buf, int num)
|
||||
{
|
||||
int i,first,len=0,c, use_bn;
|
||||
char ftmp[24], *tmp = ftmp;
|
||||
int tmpsize = sizeof ftmp;
|
||||
const char *p;
|
||||
unsigned long l;
|
||||
BIGNUM *bl = NULL;
|
||||
{
|
||||
int i, first, len = 0, c, use_bn;
|
||||
char ftmp[24], *tmp = ftmp;
|
||||
int tmpsize = sizeof ftmp;
|
||||
const char *p;
|
||||
unsigned long l;
|
||||
BIGNUM *bl = NULL;
|
||||
|
||||
if (num == 0)
|
||||
return(0);
|
||||
else if (num == -1)
|
||||
num=strlen(buf);
|
||||
if (num == 0)
|
||||
return (0);
|
||||
else if (num == -1)
|
||||
num = strlen(buf);
|
||||
|
||||
p=buf;
|
||||
c= *(p++);
|
||||
num--;
|
||||
if ((c >= '0') && (c <= '2'))
|
||||
{
|
||||
first= c-'0';
|
||||
}
|
||||
else
|
||||
{
|
||||
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_FIRST_NUM_TOO_LARGE);
|
||||
goto err;
|
||||
}
|
||||
p = buf;
|
||||
c = *(p++);
|
||||
num--;
|
||||
if ((c >= '0') && (c <= '2')) {
|
||||
first = c - '0';
|
||||
} else {
|
||||
ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_FIRST_NUM_TOO_LARGE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (num <= 0)
|
||||
{
|
||||
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_MISSING_SECOND_NUMBER);
|
||||
goto err;
|
||||
}
|
||||
c= *(p++);
|
||||
num--;
|
||||
for (;;)
|
||||
{
|
||||
if (num <= 0) break;
|
||||
if ((c != '.') && (c != ' '))
|
||||
{
|
||||
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_SEPARATOR);
|
||||
goto err;
|
||||
}
|
||||
l=0;
|
||||
use_bn = 0;
|
||||
for (;;)
|
||||
{
|
||||
if (num <= 0) break;
|
||||
num--;
|
||||
c= *(p++);
|
||||
if ((c == ' ') || (c == '.'))
|
||||
break;
|
||||
if ((c < '0') || (c > '9'))
|
||||
{
|
||||
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_INVALID_DIGIT);
|
||||
goto err;
|
||||
}
|
||||
if (!use_bn && l >= ((ULONG_MAX - 80) / 10L))
|
||||
{
|
||||
use_bn = 1;
|
||||
if (!bl)
|
||||
bl = BN_new();
|
||||
if (!bl || !BN_set_word(bl, l))
|
||||
goto err;
|
||||
}
|
||||
if (use_bn)
|
||||
{
|
||||
if (!BN_mul_word(bl, 10L)
|
||||
|| !BN_add_word(bl, c-'0'))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
l=l*10L+(long)(c-'0');
|
||||
}
|
||||
if (len == 0)
|
||||
{
|
||||
if ((first < 2) && (l >= 40))
|
||||
{
|
||||
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_SECOND_NUMBER_TOO_LARGE);
|
||||
goto err;
|
||||
}
|
||||
if (use_bn)
|
||||
{
|
||||
if (!BN_add_word(bl, first * 40))
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
l+=(long)first*40;
|
||||
}
|
||||
i=0;
|
||||
if (use_bn)
|
||||
{
|
||||
int blsize;
|
||||
blsize = BN_num_bits(bl);
|
||||
blsize = (blsize + 6)/7;
|
||||
if (blsize > tmpsize)
|
||||
{
|
||||
if (tmp != ftmp)
|
||||
OPENSSL_free(tmp);
|
||||
tmpsize = blsize + 32;
|
||||
tmp = OPENSSL_malloc(tmpsize);
|
||||
if (!tmp)
|
||||
goto err;
|
||||
}
|
||||
while(blsize--)
|
||||
tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
for (;;)
|
||||
{
|
||||
tmp[i++]=(unsigned char)l&0x7f;
|
||||
l>>=7L;
|
||||
if (l == 0L) break;
|
||||
}
|
||||
if (num <= 0) {
|
||||
ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_MISSING_SECOND_NUMBER);
|
||||
goto err;
|
||||
}
|
||||
c = *(p++);
|
||||
num--;
|
||||
for (;;) {
|
||||
if (num <= 0)
|
||||
break;
|
||||
if ((c != '.') && (c != ' ')) {
|
||||
ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_SEPARATOR);
|
||||
goto err;
|
||||
}
|
||||
l = 0;
|
||||
use_bn = 0;
|
||||
for (;;) {
|
||||
if (num <= 0)
|
||||
break;
|
||||
num--;
|
||||
c = *(p++);
|
||||
if ((c == ' ') || (c == '.'))
|
||||
break;
|
||||
if ((c < '0') || (c > '9')) {
|
||||
ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_INVALID_DIGIT);
|
||||
goto err;
|
||||
}
|
||||
if (!use_bn && l >= ((ULONG_MAX - 80) / 10L)) {
|
||||
use_bn = 1;
|
||||
if (!bl)
|
||||
bl = BN_new();
|
||||
if (!bl || !BN_set_word(bl, l))
|
||||
goto err;
|
||||
}
|
||||
if (use_bn) {
|
||||
if (!BN_mul_word(bl, 10L)
|
||||
|| !BN_add_word(bl, c - '0'))
|
||||
goto err;
|
||||
} else
|
||||
l = l * 10L + (long)(c - '0');
|
||||
}
|
||||
if (len == 0) {
|
||||
if ((first < 2) && (l >= 40)) {
|
||||
ASN1err(ASN1_F_A2D_ASN1_OBJECT,
|
||||
ASN1_R_SECOND_NUMBER_TOO_LARGE);
|
||||
goto err;
|
||||
}
|
||||
if (use_bn) {
|
||||
if (!BN_add_word(bl, first * 40))
|
||||
goto err;
|
||||
} else
|
||||
l += (long)first *40;
|
||||
}
|
||||
i = 0;
|
||||
if (use_bn) {
|
||||
int blsize;
|
||||
blsize = BN_num_bits(bl);
|
||||
blsize = (blsize + 6) / 7;
|
||||
if (blsize > tmpsize) {
|
||||
if (tmp != ftmp)
|
||||
OPENSSL_free(tmp);
|
||||
tmpsize = blsize + 32;
|
||||
tmp = OPENSSL_malloc(tmpsize);
|
||||
if (!tmp)
|
||||
goto err;
|
||||
}
|
||||
while (blsize--)
|
||||
tmp[i++] = (unsigned char)BN_div_word(bl, 0x80L);
|
||||
} else {
|
||||
|
||||
}
|
||||
if (out != NULL)
|
||||
{
|
||||
if (len+i > olen)
|
||||
{
|
||||
ASN1err(ASN1_F_A2D_ASN1_OBJECT,ASN1_R_BUFFER_TOO_SMALL);
|
||||
goto err;
|
||||
}
|
||||
while (--i > 0)
|
||||
out[len++]=tmp[i]|0x80;
|
||||
out[len++]=tmp[0];
|
||||
}
|
||||
else
|
||||
len+=i;
|
||||
}
|
||||
if (tmp != ftmp)
|
||||
OPENSSL_free(tmp);
|
||||
if (bl)
|
||||
BN_free(bl);
|
||||
return(len);
|
||||
err:
|
||||
if (tmp != ftmp)
|
||||
OPENSSL_free(tmp);
|
||||
if (bl)
|
||||
BN_free(bl);
|
||||
return(0);
|
||||
}
|
||||
for (;;) {
|
||||
tmp[i++] = (unsigned char)l & 0x7f;
|
||||
l >>= 7L;
|
||||
if (l == 0L)
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
if (out != NULL) {
|
||||
if (len + i > olen) {
|
||||
ASN1err(ASN1_F_A2D_ASN1_OBJECT, ASN1_R_BUFFER_TOO_SMALL);
|
||||
goto err;
|
||||
}
|
||||
while (--i > 0)
|
||||
out[len++] = tmp[i] | 0x80;
|
||||
out[len++] = tmp[0];
|
||||
} else
|
||||
len += i;
|
||||
}
|
||||
if (tmp != ftmp)
|
||||
OPENSSL_free(tmp);
|
||||
if (bl)
|
||||
BN_free(bl);
|
||||
return (len);
|
||||
err:
|
||||
if (tmp != ftmp)
|
||||
OPENSSL_free(tmp);
|
||||
if (bl)
|
||||
BN_free(bl);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int i2t_ASN1_OBJECT(char *buf, int buf_len, ASN1_OBJECT *a)
|
||||
{
|
||||
return OBJ_obj2txt(buf, buf_len, a, 0);
|
||||
return OBJ_obj2txt(buf, buf_len, a, 0);
|
||||
}
|
||||
|
||||
int i2a_ASN1_OBJECT(BIO *bp, ASN1_OBJECT *a)
|
||||
{
|
||||
char buf[80], *p = buf;
|
||||
int i;
|
||||
{
|
||||
char buf[80], *p = buf;
|
||||
int i;
|
||||
|
||||
if ((a == NULL) || (a->data == NULL))
|
||||
return(BIO_write(bp,"NULL",4));
|
||||
i=i2t_ASN1_OBJECT(buf,sizeof buf,a);
|
||||
if (i > (int)(sizeof(buf) - 1))
|
||||
{
|
||||
p = OPENSSL_malloc(i + 1);
|
||||
if (!p)
|
||||
return -1;
|
||||
i2t_ASN1_OBJECT(p,i + 1,a);
|
||||
}
|
||||
if (i <= 0)
|
||||
return BIO_write(bp, "<INVALID>", 9);
|
||||
BIO_write(bp,p,i);
|
||||
if (p != buf)
|
||||
OPENSSL_free(p);
|
||||
return(i);
|
||||
}
|
||||
if ((a == NULL) || (a->data == NULL))
|
||||
return (BIO_write(bp, "NULL", 4));
|
||||
i = i2t_ASN1_OBJECT(buf, sizeof buf, a);
|
||||
if (i > (int)(sizeof(buf) - 1)) {
|
||||
p = OPENSSL_malloc(i + 1);
|
||||
if (!p)
|
||||
return -1;
|
||||
i2t_ASN1_OBJECT(p, i + 1, a);
|
||||
}
|
||||
if (i <= 0)
|
||||
return BIO_write(bp, "<INVALID>", 9);
|
||||
BIO_write(bp, p, i);
|
||||
if (p != buf)
|
||||
OPENSSL_free(p);
|
||||
return (i);
|
||||
}
|
||||
|
||||
ASN1_OBJECT *d2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
|
||||
long length)
|
||||
long length)
|
||||
{
|
||||
const unsigned char *p;
|
||||
long len;
|
||||
int tag,xclass;
|
||||
int inf,i;
|
||||
ASN1_OBJECT *ret = NULL;
|
||||
p= *pp;
|
||||
inf=ASN1_get_object(&p,&len,&tag,&xclass,length);
|
||||
if (inf & 0x80)
|
||||
{
|
||||
i=ASN1_R_BAD_OBJECT_HEADER;
|
||||
goto err;
|
||||
}
|
||||
const unsigned char *p;
|
||||
long len;
|
||||
int tag, xclass;
|
||||
int inf, i;
|
||||
ASN1_OBJECT *ret = NULL;
|
||||
p = *pp;
|
||||
inf = ASN1_get_object(&p, &len, &tag, &xclass, length);
|
||||
if (inf & 0x80) {
|
||||
i = ASN1_R_BAD_OBJECT_HEADER;
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (tag != V_ASN1_OBJECT)
|
||||
{
|
||||
i=ASN1_R_EXPECTING_AN_OBJECT;
|
||||
goto err;
|
||||
}
|
||||
ret = c2i_ASN1_OBJECT(a, &p, len);
|
||||
if(ret) *pp = p;
|
||||
return ret;
|
||||
err:
|
||||
ASN1err(ASN1_F_D2I_ASN1_OBJECT,i);
|
||||
return(NULL);
|
||||
if (tag != V_ASN1_OBJECT) {
|
||||
i = ASN1_R_EXPECTING_AN_OBJECT;
|
||||
goto err;
|
||||
}
|
||||
ret = c2i_ASN1_OBJECT(a, &p, len);
|
||||
if (ret)
|
||||
*pp = p;
|
||||
return ret;
|
||||
err:
|
||||
ASN1err(ASN1_F_D2I_ASN1_OBJECT, i);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ASN1_OBJECT *c2i_ASN1_OBJECT(ASN1_OBJECT **a, const unsigned char **pp,
|
||||
long len)
|
||||
{
|
||||
ASN1_OBJECT *ret=NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *data;
|
||||
int i;
|
||||
/* Sanity check OID encoding: can't have leading 0x80 in
|
||||
* subidentifiers, see: X.690 8.19.2
|
||||
*/
|
||||
for (i = 0, p = *pp; i < len; i++, p++)
|
||||
{
|
||||
if (*p == 0x80 && (!i || !(p[-1] & 0x80)))
|
||||
{
|
||||
ASN1err(ASN1_F_C2I_ASN1_OBJECT,ASN1_R_INVALID_OBJECT_ENCODING);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
long len)
|
||||
{
|
||||
ASN1_OBJECT *ret = NULL;
|
||||
const unsigned char *p;
|
||||
unsigned char *data;
|
||||
int i, length;
|
||||
|
||||
/* only the ASN1_OBJECTs from the 'table' will have values
|
||||
* for ->sn or ->ln */
|
||||
if ((a == NULL) || ((*a) == NULL) ||
|
||||
!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC))
|
||||
{
|
||||
if ((ret=ASN1_OBJECT_new()) == NULL) return(NULL);
|
||||
}
|
||||
else ret=(*a);
|
||||
/*
|
||||
* Sanity check OID encoding. Need at least one content octet. MSB must
|
||||
* be clear in the last octet. can't have leading 0x80 in subidentifiers,
|
||||
* see: X.690 8.19.2
|
||||
*/
|
||||
if (len <= 0 || len > INT_MAX || pp == NULL || (p = *pp) == NULL ||
|
||||
p[len - 1] & 0x80) {
|
||||
ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
|
||||
return NULL;
|
||||
}
|
||||
/* Now 0 < len <= INT_MAX, so the cast is safe. */
|
||||
length = (int)len;
|
||||
for (i = 0; i < length; i++, p++) {
|
||||
if (*p == 0x80 && (!i || !(p[-1] & 0x80))) {
|
||||
ASN1err(ASN1_F_C2I_ASN1_OBJECT, ASN1_R_INVALID_OBJECT_ENCODING);
|
||||
return NULL;
|
||||
}
|
||||
}
|
||||
|
||||
p= *pp;
|
||||
/* detach data from object */
|
||||
data = (unsigned char *)ret->data;
|
||||
ret->data = NULL;
|
||||
/* once detached we can change it */
|
||||
if ((data == NULL) || (ret->length < len))
|
||||
{
|
||||
ret->length=0;
|
||||
if (data != NULL) OPENSSL_free(data);
|
||||
data=(unsigned char *)OPENSSL_malloc(len ? (int)len : 1);
|
||||
if (data == NULL)
|
||||
{ i=ERR_R_MALLOC_FAILURE; goto err; }
|
||||
ret->flags|=ASN1_OBJECT_FLAG_DYNAMIC_DATA;
|
||||
}
|
||||
memcpy(data,p,(int)len);
|
||||
/* reattach data to object, after which it remains const */
|
||||
ret->data =data;
|
||||
ret->length=(int)len;
|
||||
ret->sn=NULL;
|
||||
ret->ln=NULL;
|
||||
/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
|
||||
p+=len;
|
||||
/*
|
||||
* only the ASN1_OBJECTs from the 'table' will have values for ->sn or
|
||||
* ->ln
|
||||
*/
|
||||
if ((a == NULL) || ((*a) == NULL) ||
|
||||
!((*a)->flags & ASN1_OBJECT_FLAG_DYNAMIC)) {
|
||||
if ((ret = ASN1_OBJECT_new()) == NULL)
|
||||
return (NULL);
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
if (a != NULL) (*a)=ret;
|
||||
*pp=p;
|
||||
return(ret);
|
||||
err:
|
||||
ASN1err(ASN1_F_C2I_ASN1_OBJECT,i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
ASN1_OBJECT_free(ret);
|
||||
return(NULL);
|
||||
}
|
||||
p = *pp;
|
||||
/* detach data from object */
|
||||
data = (unsigned char *)ret->data;
|
||||
ret->data = NULL;
|
||||
/* once detached we can change it */
|
||||
if ((data == NULL) || (ret->length < length)) {
|
||||
ret->length = 0;
|
||||
if (data != NULL)
|
||||
OPENSSL_free(data);
|
||||
data = (unsigned char *)OPENSSL_malloc(length);
|
||||
if (data == NULL) {
|
||||
i = ERR_R_MALLOC_FAILURE;
|
||||
goto err;
|
||||
}
|
||||
ret->flags |= ASN1_OBJECT_FLAG_DYNAMIC_DATA;
|
||||
}
|
||||
memcpy(data, p, length);
|
||||
/* reattach data to object, after which it remains const */
|
||||
ret->data = data;
|
||||
ret->length = length;
|
||||
ret->sn = NULL;
|
||||
ret->ln = NULL;
|
||||
/* ret->flags=ASN1_OBJECT_FLAG_DYNAMIC; we know it is dynamic */
|
||||
p += length;
|
||||
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = p;
|
||||
return (ret);
|
||||
err:
|
||||
ASN1err(ASN1_F_C2I_ASN1_OBJECT, i);
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
ASN1_OBJECT_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ASN1_OBJECT *ASN1_OBJECT_new(void)
|
||||
{
|
||||
ASN1_OBJECT *ret;
|
||||
{
|
||||
ASN1_OBJECT *ret;
|
||||
|
||||
ret=(ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
|
||||
if (ret == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_OBJECT_NEW,ERR_R_MALLOC_FAILURE);
|
||||
return(NULL);
|
||||
}
|
||||
ret->length=0;
|
||||
ret->data=NULL;
|
||||
ret->nid=0;
|
||||
ret->sn=NULL;
|
||||
ret->ln=NULL;
|
||||
ret->flags=ASN1_OBJECT_FLAG_DYNAMIC;
|
||||
return(ret);
|
||||
}
|
||||
ret = (ASN1_OBJECT *)OPENSSL_malloc(sizeof(ASN1_OBJECT));
|
||||
if (ret == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_OBJECT_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
ret->length = 0;
|
||||
ret->data = NULL;
|
||||
ret->nid = 0;
|
||||
ret->sn = NULL;
|
||||
ret->ln = NULL;
|
||||
ret->flags = ASN1_OBJECT_FLAG_DYNAMIC;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void ASN1_OBJECT_free(ASN1_OBJECT *a)
|
||||
{
|
||||
if (a == NULL) return;
|
||||
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS)
|
||||
{
|
||||
#ifndef CONST_STRICT /* disable purely for compile-time strict const checking. Doing this on a "real" compile will cause memory leaks */
|
||||
if (a->sn != NULL) OPENSSL_free((void *)a->sn);
|
||||
if (a->ln != NULL) OPENSSL_free((void *)a->ln);
|
||||
{
|
||||
if (a == NULL)
|
||||
return;
|
||||
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_STRINGS) {
|
||||
#ifndef CONST_STRICT /* disable purely for compile-time strict
|
||||
* const checking. Doing this on a "real"
|
||||
* compile will cause memory leaks */
|
||||
if (a->sn != NULL)
|
||||
OPENSSL_free((void *)a->sn);
|
||||
if (a->ln != NULL)
|
||||
OPENSSL_free((void *)a->ln);
|
||||
#endif
|
||||
a->sn=a->ln=NULL;
|
||||
}
|
||||
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA)
|
||||
{
|
||||
if (a->data != NULL) OPENSSL_free((void *)a->data);
|
||||
a->data=NULL;
|
||||
a->length=0;
|
||||
}
|
||||
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
|
||||
OPENSSL_free(a);
|
||||
}
|
||||
a->sn = a->ln = NULL;
|
||||
}
|
||||
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC_DATA) {
|
||||
if (a->data != NULL)
|
||||
OPENSSL_free((void *)a->data);
|
||||
a->data = NULL;
|
||||
a->length = 0;
|
||||
}
|
||||
if (a->flags & ASN1_OBJECT_FLAG_DYNAMIC)
|
||||
OPENSSL_free(a);
|
||||
}
|
||||
|
||||
ASN1_OBJECT *ASN1_OBJECT_create(int nid, unsigned char *data, int len,
|
||||
const char *sn, const char *ln)
|
||||
{
|
||||
ASN1_OBJECT o;
|
||||
const char *sn, const char *ln)
|
||||
{
|
||||
ASN1_OBJECT o;
|
||||
|
||||
o.sn=sn;
|
||||
o.ln=ln;
|
||||
o.data=data;
|
||||
o.nid=nid;
|
||||
o.length=len;
|
||||
o.flags=ASN1_OBJECT_FLAG_DYNAMIC|ASN1_OBJECT_FLAG_DYNAMIC_STRINGS|
|
||||
ASN1_OBJECT_FLAG_DYNAMIC_DATA;
|
||||
return(OBJ_dup(&o));
|
||||
}
|
||||
o.sn = sn;
|
||||
o.ln = ln;
|
||||
o.data = data;
|
||||
o.nid = nid;
|
||||
o.length = len;
|
||||
o.flags = ASN1_OBJECT_FLAG_DYNAMIC | ASN1_OBJECT_FLAG_DYNAMIC_STRINGS |
|
||||
ASN1_OBJECT_FLAG_DYNAMIC_DATA;
|
||||
return (OBJ_dup(&o));
|
||||
}
|
||||
|
||||
IMPLEMENT_STACK_OF(ASN1_OBJECT)
|
||||
|
||||
IMPLEMENT_ASN1_SET_OF(ASN1_OBJECT)
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -61,11 +61,18 @@
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
ASN1_OCTET_STRING *ASN1_OCTET_STRING_dup(const ASN1_OCTET_STRING *x)
|
||||
{ return M_ASN1_OCTET_STRING_dup(x); }
|
||||
{
|
||||
return M_ASN1_OCTET_STRING_dup(x);
|
||||
}
|
||||
|
||||
int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a, const ASN1_OCTET_STRING *b)
|
||||
{ return M_ASN1_OCTET_STRING_cmp(a, b); }
|
||||
|
||||
int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d, int len)
|
||||
{ return M_ASN1_OCTET_STRING_set(x, d, len); }
|
||||
int ASN1_OCTET_STRING_cmp(const ASN1_OCTET_STRING *a,
|
||||
const ASN1_OCTET_STRING *b)
|
||||
{
|
||||
return M_ASN1_OCTET_STRING_cmp(a, b);
|
||||
}
|
||||
|
||||
int ASN1_OCTET_STRING_set(ASN1_OCTET_STRING *x, const unsigned char *d,
|
||||
int len)
|
||||
{
|
||||
return M_ASN1_OCTET_STRING_set(x, d, len);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -61,67 +61,69 @@
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
int ASN1_PRINTABLE_type(const unsigned char *s, int len)
|
||||
{
|
||||
int c;
|
||||
int ia5=0;
|
||||
int t61=0;
|
||||
{
|
||||
int c;
|
||||
int ia5 = 0;
|
||||
int t61 = 0;
|
||||
|
||||
if (len <= 0) len= -1;
|
||||
if (s == NULL) return(V_ASN1_PRINTABLESTRING);
|
||||
if (len <= 0)
|
||||
len = -1;
|
||||
if (s == NULL)
|
||||
return (V_ASN1_PRINTABLESTRING);
|
||||
|
||||
while ((*s) && (len-- != 0))
|
||||
{
|
||||
c= *(s++);
|
||||
while ((*s) && (len-- != 0)) {
|
||||
c = *(s++);
|
||||
#ifndef CHARSET_EBCDIC
|
||||
if (!( ((c >= 'a') && (c <= 'z')) ||
|
||||
((c >= 'A') && (c <= 'Z')) ||
|
||||
(c == ' ') ||
|
||||
((c >= '0') && (c <= '9')) ||
|
||||
(c == ' ') || (c == '\'') ||
|
||||
(c == '(') || (c == ')') ||
|
||||
(c == '+') || (c == ',') ||
|
||||
(c == '-') || (c == '.') ||
|
||||
(c == '/') || (c == ':') ||
|
||||
(c == '=') || (c == '?')))
|
||||
ia5=1;
|
||||
if (c&0x80)
|
||||
t61=1;
|
||||
if (!(((c >= 'a') && (c <= 'z')) ||
|
||||
((c >= 'A') && (c <= 'Z')) ||
|
||||
(c == ' ') ||
|
||||
((c >= '0') && (c <= '9')) ||
|
||||
(c == ' ') || (c == '\'') ||
|
||||
(c == '(') || (c == ')') ||
|
||||
(c == '+') || (c == ',') ||
|
||||
(c == '-') || (c == '.') ||
|
||||
(c == '/') || (c == ':') || (c == '=') || (c == '?')))
|
||||
ia5 = 1;
|
||||
if (c & 0x80)
|
||||
t61 = 1;
|
||||
#else
|
||||
if (!isalnum(c) && (c != ' ') &&
|
||||
strchr("'()+,-./:=?", c) == NULL)
|
||||
ia5=1;
|
||||
if (os_toascii[c] & 0x80)
|
||||
t61=1;
|
||||
if (!isalnum(c) && (c != ' ') && strchr("'()+,-./:=?", c) == NULL)
|
||||
ia5 = 1;
|
||||
if (os_toascii[c] & 0x80)
|
||||
t61 = 1;
|
||||
#endif
|
||||
}
|
||||
if (t61) return(V_ASN1_T61STRING);
|
||||
if (ia5) return(V_ASN1_IA5STRING);
|
||||
return(V_ASN1_PRINTABLESTRING);
|
||||
}
|
||||
}
|
||||
if (t61)
|
||||
return (V_ASN1_T61STRING);
|
||||
if (ia5)
|
||||
return (V_ASN1_IA5STRING);
|
||||
return (V_ASN1_PRINTABLESTRING);
|
||||
}
|
||||
|
||||
int ASN1_UNIVERSALSTRING_to_string(ASN1_UNIVERSALSTRING *s)
|
||||
{
|
||||
int i;
|
||||
unsigned char *p;
|
||||
{
|
||||
int i;
|
||||
unsigned char *p;
|
||||
|
||||
if (s->type != V_ASN1_UNIVERSALSTRING) return(0);
|
||||
if ((s->length%4) != 0) return(0);
|
||||
p=s->data;
|
||||
for (i=0; i<s->length; i+=4)
|
||||
{
|
||||
if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
|
||||
break;
|
||||
else
|
||||
p+=4;
|
||||
}
|
||||
if (i < s->length) return(0);
|
||||
p=s->data;
|
||||
for (i=3; i<s->length; i+=4)
|
||||
{
|
||||
*(p++)=s->data[i];
|
||||
}
|
||||
*(p)='\0';
|
||||
s->length/=4;
|
||||
s->type=ASN1_PRINTABLE_type(s->data,s->length);
|
||||
return(1);
|
||||
}
|
||||
if (s->type != V_ASN1_UNIVERSALSTRING)
|
||||
return (0);
|
||||
if ((s->length % 4) != 0)
|
||||
return (0);
|
||||
p = s->data;
|
||||
for (i = 0; i < s->length; i += 4) {
|
||||
if ((p[0] != '\0') || (p[1] != '\0') || (p[2] != '\0'))
|
||||
break;
|
||||
else
|
||||
p += 4;
|
||||
}
|
||||
if (i < s->length)
|
||||
return (0);
|
||||
p = s->data;
|
||||
for (i = 3; i < s->length; i += 4) {
|
||||
*(p++) = s->data[i];
|
||||
}
|
||||
*(p) = '\0';
|
||||
s->length /= 4;
|
||||
s->type = ASN1_PRINTABLE_type(s->data, s->length);
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,180 +62,177 @@
|
||||
|
||||
#ifndef NO_ASN1_OLD
|
||||
|
||||
typedef struct
|
||||
{
|
||||
typedef struct {
|
||||
unsigned char *pbData;
|
||||
int cbData;
|
||||
} MYBLOB;
|
||||
} MYBLOB;
|
||||
|
||||
/* SetBlobCmp
|
||||
* This function compares two elements of SET_OF block
|
||||
/*
|
||||
* SetBlobCmp This function compares two elements of SET_OF block
|
||||
*/
|
||||
static int SetBlobCmp(const void *elem1, const void *elem2 )
|
||||
{
|
||||
static int SetBlobCmp(const void *elem1, const void *elem2)
|
||||
{
|
||||
const MYBLOB *b1 = (const MYBLOB *)elem1;
|
||||
const MYBLOB *b2 = (const MYBLOB *)elem2;
|
||||
int r;
|
||||
|
||||
r = memcmp(b1->pbData, b2->pbData,
|
||||
b1->cbData < b2->cbData ? b1->cbData : b2->cbData);
|
||||
if(r != 0)
|
||||
return r;
|
||||
return b1->cbData-b2->cbData;
|
||||
}
|
||||
b1->cbData < b2->cbData ? b1->cbData : b2->cbData);
|
||||
if (r != 0)
|
||||
return r;
|
||||
return b1->cbData - b2->cbData;
|
||||
}
|
||||
|
||||
/* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE) */
|
||||
/*
|
||||
* int is_set: if TRUE, then sort the contents (i.e. it isn't a SEQUENCE)
|
||||
*/
|
||||
int i2d_ASN1_SET(STACK_OF(OPENSSL_BLOCK) *a, unsigned char **pp,
|
||||
i2d_of_void *i2d, int ex_tag, int ex_class,
|
||||
int is_set)
|
||||
{
|
||||
int ret=0,r;
|
||||
int i;
|
||||
unsigned char *p;
|
||||
unsigned char *pStart, *pTempMem;
|
||||
MYBLOB *rgSetBlob;
|
||||
int totSize;
|
||||
i2d_of_void *i2d, int ex_tag, int ex_class, int is_set)
|
||||
{
|
||||
int ret = 0, r;
|
||||
int i;
|
||||
unsigned char *p;
|
||||
unsigned char *pStart, *pTempMem;
|
||||
MYBLOB *rgSetBlob;
|
||||
int totSize;
|
||||
|
||||
if (a == NULL) return(0);
|
||||
for (i=sk_OPENSSL_BLOCK_num(a)-1; i>=0; i--)
|
||||
ret+=i2d(sk_OPENSSL_BLOCK_value(a,i),NULL);
|
||||
r=ASN1_object_size(1,ret,ex_tag);
|
||||
if (pp == NULL) return(r);
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
for (i = sk_OPENSSL_BLOCK_num(a) - 1; i >= 0; i--)
|
||||
ret += i2d(sk_OPENSSL_BLOCK_value(a, i), NULL);
|
||||
r = ASN1_object_size(1, ret, ex_tag);
|
||||
if (pp == NULL)
|
||||
return (r);
|
||||
|
||||
p= *pp;
|
||||
ASN1_put_object(&p,1,ret,ex_tag,ex_class);
|
||||
p = *pp;
|
||||
ASN1_put_object(&p, 1, ret, ex_tag, ex_class);
|
||||
|
||||
/* Modified by gp@nsj.co.jp */
|
||||
/* And then again by Ben */
|
||||
/* And again by Steve */
|
||||
/* And then again by Ben */
|
||||
/* And again by Steve */
|
||||
|
||||
if(!is_set || (sk_OPENSSL_BLOCK_num(a) < 2))
|
||||
{
|
||||
for (i=0; i<sk_OPENSSL_BLOCK_num(a); i++)
|
||||
i2d(sk_OPENSSL_BLOCK_value(a,i),&p);
|
||||
if (!is_set || (sk_OPENSSL_BLOCK_num(a) < 2)) {
|
||||
for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++)
|
||||
i2d(sk_OPENSSL_BLOCK_value(a, i), &p);
|
||||
|
||||
*pp=p;
|
||||
return(r);
|
||||
}
|
||||
*pp = p;
|
||||
return (r);
|
||||
}
|
||||
|
||||
pStart = p; /* Catch the beg of Setblobs*/
|
||||
/* In this array we will store the SET blobs */
|
||||
rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB));
|
||||
if (rgSetBlob == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
|
||||
return(0);
|
||||
}
|
||||
pStart = p; /* Catch the beg of Setblobs */
|
||||
/* In this array we will store the SET blobs */
|
||||
rgSetBlob = OPENSSL_malloc(sk_OPENSSL_BLOCK_num(a) * sizeof(MYBLOB));
|
||||
if (rgSetBlob == NULL) {
|
||||
ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
for (i=0; i<sk_OPENSSL_BLOCK_num(a); i++)
|
||||
{
|
||||
rgSetBlob[i].pbData = p; /* catch each set encode blob */
|
||||
i2d(sk_OPENSSL_BLOCK_value(a,i),&p);
|
||||
rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this
|
||||
SetBlob
|
||||
*/
|
||||
}
|
||||
*pp=p;
|
||||
totSize = p - pStart; /* This is the total size of all set blobs */
|
||||
for (i = 0; i < sk_OPENSSL_BLOCK_num(a); i++) {
|
||||
rgSetBlob[i].pbData = p; /* catch each set encode blob */
|
||||
i2d(sk_OPENSSL_BLOCK_value(a, i), &p);
|
||||
rgSetBlob[i].cbData = p - rgSetBlob[i].pbData; /* Length of this
|
||||
* SetBlob */
|
||||
}
|
||||
*pp = p;
|
||||
totSize = p - pStart; /* This is the total size of all set blobs */
|
||||
|
||||
/* Now we have to sort the blobs. I am using a simple algo.
|
||||
*Sort ptrs *Copy to temp-mem *Copy from temp-mem to user-mem*/
|
||||
qsort( rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp);
|
||||
if (!(pTempMem = OPENSSL_malloc(totSize)))
|
||||
{
|
||||
ASN1err(ASN1_F_I2D_ASN1_SET,ERR_R_MALLOC_FAILURE);
|
||||
return(0);
|
||||
}
|
||||
/*
|
||||
* Now we have to sort the blobs. I am using a simple algo. *Sort ptrs
|
||||
* *Copy to temp-mem *Copy from temp-mem to user-mem
|
||||
*/
|
||||
qsort(rgSetBlob, sk_OPENSSL_BLOCK_num(a), sizeof(MYBLOB), SetBlobCmp);
|
||||
if (!(pTempMem = OPENSSL_malloc(totSize))) {
|
||||
ASN1err(ASN1_F_I2D_ASN1_SET, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
|
||||
/* Copy to temp mem */
|
||||
p = pTempMem;
|
||||
for(i=0; i<sk_OPENSSL_BLOCK_num(a); ++i)
|
||||
{
|
||||
memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
|
||||
p += rgSetBlob[i].cbData;
|
||||
}
|
||||
p = pTempMem;
|
||||
for (i = 0; i < sk_OPENSSL_BLOCK_num(a); ++i) {
|
||||
memcpy(p, rgSetBlob[i].pbData, rgSetBlob[i].cbData);
|
||||
p += rgSetBlob[i].cbData;
|
||||
}
|
||||
|
||||
/* Copy back to user mem*/
|
||||
memcpy(pStart, pTempMem, totSize);
|
||||
OPENSSL_free(pTempMem);
|
||||
OPENSSL_free(rgSetBlob);
|
||||
memcpy(pStart, pTempMem, totSize);
|
||||
OPENSSL_free(pTempMem);
|
||||
OPENSSL_free(rgSetBlob);
|
||||
|
||||
return(r);
|
||||
}
|
||||
return (r);
|
||||
}
|
||||
|
||||
STACK_OF(OPENSSL_BLOCK) *d2i_ASN1_SET(STACK_OF(OPENSSL_BLOCK) **a,
|
||||
const unsigned char **pp,
|
||||
long length, d2i_of_void *d2i,
|
||||
void (*free_func)(OPENSSL_BLOCK), int ex_tag,
|
||||
int ex_class)
|
||||
{
|
||||
ASN1_const_CTX c;
|
||||
STACK_OF(OPENSSL_BLOCK) *ret=NULL;
|
||||
const unsigned char **pp,
|
||||
long length, d2i_of_void *d2i,
|
||||
void (*free_func) (OPENSSL_BLOCK),
|
||||
int ex_tag, int ex_class)
|
||||
{
|
||||
ASN1_const_CTX c;
|
||||
STACK_OF(OPENSSL_BLOCK) *ret = NULL;
|
||||
|
||||
if ((a == NULL) || ((*a) == NULL))
|
||||
{
|
||||
if ((ret=sk_OPENSSL_BLOCK_new_null()) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_ASN1_SET,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
else
|
||||
ret=(*a);
|
||||
if ((a == NULL) || ((*a) == NULL)) {
|
||||
if ((ret = sk_OPENSSL_BLOCK_new_null()) == NULL) {
|
||||
ASN1err(ASN1_F_D2I_ASN1_SET, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
} else
|
||||
ret = (*a);
|
||||
|
||||
c.p= *pp;
|
||||
c.max=(length == 0)?0:(c.p+length);
|
||||
c.p = *pp;
|
||||
c.max = (length == 0) ? 0 : (c.p + length);
|
||||
|
||||
c.inf=ASN1_get_object(&c.p,&c.slen,&c.tag,&c.xclass,c.max-c.p);
|
||||
if (c.inf & 0x80) goto err;
|
||||
if (ex_class != c.xclass)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_CLASS);
|
||||
goto err;
|
||||
}
|
||||
if (ex_tag != c.tag)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_BAD_TAG);
|
||||
goto err;
|
||||
}
|
||||
if ((c.slen+c.p) > c.max)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_LENGTH_ERROR);
|
||||
goto err;
|
||||
}
|
||||
/* check for infinite constructed - it can be as long
|
||||
* as the amount of data passed to us */
|
||||
if (c.inf == (V_ASN1_CONSTRUCTED+1))
|
||||
c.slen=length+ *pp-c.p;
|
||||
c.max=c.p+c.slen;
|
||||
c.inf = ASN1_get_object(&c.p, &c.slen, &c.tag, &c.xclass, c.max - c.p);
|
||||
if (c.inf & 0x80)
|
||||
goto err;
|
||||
if (ex_class != c.xclass) {
|
||||
ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_CLASS);
|
||||
goto err;
|
||||
}
|
||||
if (ex_tag != c.tag) {
|
||||
ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_BAD_TAG);
|
||||
goto err;
|
||||
}
|
||||
if ((c.slen + c.p) > c.max) {
|
||||
ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_LENGTH_ERROR);
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* check for infinite constructed - it can be as long as the amount of
|
||||
* data passed to us
|
||||
*/
|
||||
if (c.inf == (V_ASN1_CONSTRUCTED + 1))
|
||||
c.slen = length + *pp - c.p;
|
||||
c.max = c.p + c.slen;
|
||||
|
||||
while (c.p < c.max)
|
||||
{
|
||||
char *s;
|
||||
while (c.p < c.max) {
|
||||
char *s;
|
||||
|
||||
if (M_ASN1_D2I_end_sequence()) break;
|
||||
/* XXX: This was called with 4 arguments, incorrectly, it seems
|
||||
if ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL) */
|
||||
if ((s=d2i(NULL,&c.p,c.slen)) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_ASN1_SET,ASN1_R_ERROR_PARSING_SET_ELEMENT);
|
||||
asn1_add_error(*pp,(int)(c.p- *pp));
|
||||
goto err;
|
||||
}
|
||||
if (!sk_OPENSSL_BLOCK_push(ret,s)) goto err;
|
||||
}
|
||||
if (a != NULL) (*a)=ret;
|
||||
*pp=c.p;
|
||||
return(ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
{
|
||||
if (free_func != NULL)
|
||||
sk_OPENSSL_BLOCK_pop_free(ret,free_func);
|
||||
else
|
||||
sk_OPENSSL_BLOCK_free(ret);
|
||||
}
|
||||
return(NULL);
|
||||
}
|
||||
if (M_ASN1_D2I_end_sequence())
|
||||
break;
|
||||
/*
|
||||
* XXX: This was called with 4 arguments, incorrectly, it seems if
|
||||
* ((s=func(NULL,&c.p,c.slen,c.max-c.p)) == NULL)
|
||||
*/
|
||||
if ((s = d2i(NULL, &c.p, c.slen)) == NULL) {
|
||||
ASN1err(ASN1_F_D2I_ASN1_SET, ASN1_R_ERROR_PARSING_SET_ELEMENT);
|
||||
asn1_add_error(*pp, (int)(c.p - *pp));
|
||||
goto err;
|
||||
}
|
||||
if (!sk_OPENSSL_BLOCK_push(ret, s))
|
||||
goto err;
|
||||
}
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
*pp = c.p;
|
||||
return (ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret))) {
|
||||
if (free_func != NULL)
|
||||
sk_OPENSSL_BLOCK_pop_free(ret, free_func);
|
||||
else
|
||||
sk_OPENSSL_BLOCK_free(ret);
|
||||
}
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -63,7 +63,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -128,206 +128,204 @@
|
||||
#ifndef NO_ASN1_OLD
|
||||
|
||||
int ASN1_sign(i2d_of_void *i2d, X509_ALGOR *algor1, X509_ALGOR *algor2,
|
||||
ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
|
||||
const EVP_MD *type)
|
||||
{
|
||||
EVP_MD_CTX ctx;
|
||||
unsigned char *p,*buf_in=NULL,*buf_out=NULL;
|
||||
int i,inl=0,outl=0,outll=0;
|
||||
X509_ALGOR *a;
|
||||
ASN1_BIT_STRING *signature, char *data, EVP_PKEY *pkey,
|
||||
const EVP_MD *type)
|
||||
{
|
||||
EVP_MD_CTX ctx;
|
||||
unsigned char *p, *buf_in = NULL, *buf_out = NULL;
|
||||
int i, inl = 0, outl = 0, outll = 0;
|
||||
X509_ALGOR *a;
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
for (i=0; i<2; i++)
|
||||
{
|
||||
if (i == 0)
|
||||
a=algor1;
|
||||
else
|
||||
a=algor2;
|
||||
if (a == NULL) continue;
|
||||
if (type->pkey_type == NID_dsaWithSHA1)
|
||||
{
|
||||
/* special case: RFC 2459 tells us to omit 'parameters'
|
||||
* with id-dsa-with-sha1 */
|
||||
ASN1_TYPE_free(a->parameter);
|
||||
a->parameter = NULL;
|
||||
}
|
||||
else if ((a->parameter == NULL) ||
|
||||
(a->parameter->type != V_ASN1_NULL))
|
||||
{
|
||||
ASN1_TYPE_free(a->parameter);
|
||||
if ((a->parameter=ASN1_TYPE_new()) == NULL) goto err;
|
||||
a->parameter->type=V_ASN1_NULL;
|
||||
}
|
||||
ASN1_OBJECT_free(a->algorithm);
|
||||
a->algorithm=OBJ_nid2obj(type->pkey_type);
|
||||
if (a->algorithm == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_UNKNOWN_OBJECT_TYPE);
|
||||
goto err;
|
||||
}
|
||||
if (a->algorithm->length == 0)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_SIGN,ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
inl=i2d(data,NULL);
|
||||
buf_in=(unsigned char *)OPENSSL_malloc((unsigned int)inl);
|
||||
outll=outl=EVP_PKEY_size(pkey);
|
||||
buf_out=(unsigned char *)OPENSSL_malloc((unsigned int)outl);
|
||||
if ((buf_in == NULL) || (buf_out == NULL))
|
||||
{
|
||||
outl=0;
|
||||
ASN1err(ASN1_F_ASN1_SIGN,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
p=buf_in;
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
for (i = 0; i < 2; i++) {
|
||||
if (i == 0)
|
||||
a = algor1;
|
||||
else
|
||||
a = algor2;
|
||||
if (a == NULL)
|
||||
continue;
|
||||
if (type->pkey_type == NID_dsaWithSHA1) {
|
||||
/*
|
||||
* special case: RFC 2459 tells us to omit 'parameters' with
|
||||
* id-dsa-with-sha1
|
||||
*/
|
||||
ASN1_TYPE_free(a->parameter);
|
||||
a->parameter = NULL;
|
||||
} else if ((a->parameter == NULL) ||
|
||||
(a->parameter->type != V_ASN1_NULL)) {
|
||||
ASN1_TYPE_free(a->parameter);
|
||||
if ((a->parameter = ASN1_TYPE_new()) == NULL)
|
||||
goto err;
|
||||
a->parameter->type = V_ASN1_NULL;
|
||||
}
|
||||
ASN1_OBJECT_free(a->algorithm);
|
||||
a->algorithm = OBJ_nid2obj(type->pkey_type);
|
||||
if (a->algorithm == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_SIGN, ASN1_R_UNKNOWN_OBJECT_TYPE);
|
||||
goto err;
|
||||
}
|
||||
if (a->algorithm->length == 0) {
|
||||
ASN1err(ASN1_F_ASN1_SIGN,
|
||||
ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
inl = i2d(data, NULL);
|
||||
buf_in = (unsigned char *)OPENSSL_malloc((unsigned int)inl);
|
||||
outll = outl = EVP_PKEY_size(pkey);
|
||||
buf_out = (unsigned char *)OPENSSL_malloc((unsigned int)outl);
|
||||
if ((buf_in == NULL) || (buf_out == NULL)) {
|
||||
outl = 0;
|
||||
ASN1err(ASN1_F_ASN1_SIGN, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
p = buf_in;
|
||||
|
||||
i2d(data,&p);
|
||||
if (!EVP_SignInit_ex(&ctx,type, NULL)
|
||||
|| !EVP_SignUpdate(&ctx,(unsigned char *)buf_in,inl)
|
||||
|| !EVP_SignFinal(&ctx,(unsigned char *)buf_out,
|
||||
(unsigned int *)&outl,pkey))
|
||||
{
|
||||
outl=0;
|
||||
ASN1err(ASN1_F_ASN1_SIGN,ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (signature->data != NULL) OPENSSL_free(signature->data);
|
||||
signature->data=buf_out;
|
||||
buf_out=NULL;
|
||||
signature->length=outl;
|
||||
/* In the interests of compatibility, I'll make sure that
|
||||
* the bit string has a 'not-used bits' value of 0
|
||||
*/
|
||||
signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
|
||||
signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
|
||||
err:
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
if (buf_in != NULL)
|
||||
{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
|
||||
if (buf_out != NULL)
|
||||
{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
|
||||
return(outl);
|
||||
}
|
||||
i2d(data, &p);
|
||||
if (!EVP_SignInit_ex(&ctx, type, NULL)
|
||||
|| !EVP_SignUpdate(&ctx, (unsigned char *)buf_in, inl)
|
||||
|| !EVP_SignFinal(&ctx, (unsigned char *)buf_out,
|
||||
(unsigned int *)&outl, pkey)) {
|
||||
outl = 0;
|
||||
ASN1err(ASN1_F_ASN1_SIGN, ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (signature->data != NULL)
|
||||
OPENSSL_free(signature->data);
|
||||
signature->data = buf_out;
|
||||
buf_out = NULL;
|
||||
signature->length = outl;
|
||||
/*
|
||||
* In the interests of compatibility, I'll make sure that the bit string
|
||||
* has a 'not-used bits' value of 0
|
||||
*/
|
||||
signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
|
||||
signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
|
||||
err:
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
if (buf_in != NULL) {
|
||||
OPENSSL_cleanse((char *)buf_in, (unsigned int)inl);
|
||||
OPENSSL_free(buf_in);
|
||||
}
|
||||
if (buf_out != NULL) {
|
||||
OPENSSL_cleanse((char *)buf_out, outll);
|
||||
OPENSSL_free(buf_out);
|
||||
}
|
||||
return (outl);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1, X509_ALGOR *algor2,
|
||||
ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey,
|
||||
const EVP_MD *type)
|
||||
{
|
||||
EVP_MD_CTX ctx;
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey))
|
||||
{
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
return 0;
|
||||
}
|
||||
return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
|
||||
}
|
||||
|
||||
int ASN1_item_sign(const ASN1_ITEM *it, X509_ALGOR *algor1,
|
||||
X509_ALGOR *algor2, ASN1_BIT_STRING *signature, void *asn,
|
||||
EVP_PKEY *pkey, const EVP_MD *type)
|
||||
{
|
||||
EVP_MD_CTX ctx;
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
if (!EVP_DigestSignInit(&ctx, NULL, type, NULL, pkey)) {
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
return 0;
|
||||
}
|
||||
return ASN1_item_sign_ctx(it, algor1, algor2, signature, asn, &ctx);
|
||||
}
|
||||
|
||||
int ASN1_item_sign_ctx(const ASN1_ITEM *it,
|
||||
X509_ALGOR *algor1, X509_ALGOR *algor2,
|
||||
ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
|
||||
{
|
||||
const EVP_MD *type;
|
||||
EVP_PKEY *pkey;
|
||||
unsigned char *buf_in=NULL,*buf_out=NULL;
|
||||
size_t inl=0,outl=0,outll=0;
|
||||
int signid, paramtype;
|
||||
int rv;
|
||||
X509_ALGOR *algor1, X509_ALGOR *algor2,
|
||||
ASN1_BIT_STRING *signature, void *asn, EVP_MD_CTX *ctx)
|
||||
{
|
||||
const EVP_MD *type;
|
||||
EVP_PKEY *pkey;
|
||||
unsigned char *buf_in = NULL, *buf_out = NULL;
|
||||
size_t inl = 0, outl = 0, outll = 0;
|
||||
int signid, paramtype;
|
||||
int rv;
|
||||
|
||||
type = EVP_MD_CTX_md(ctx);
|
||||
pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
|
||||
type = EVP_MD_CTX_md(ctx);
|
||||
pkey = EVP_PKEY_CTX_get0_pkey(ctx->pctx);
|
||||
|
||||
if (!type || !pkey)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
|
||||
return 0;
|
||||
}
|
||||
if (!type || !pkey) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ASN1_R_CONTEXT_NOT_INITIALISED);
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (pkey->ameth->item_sign)
|
||||
{
|
||||
rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2,
|
||||
signature);
|
||||
if (rv == 1)
|
||||
outl = signature->length;
|
||||
/* Return value meanings:
|
||||
* <=0: error.
|
||||
* 1: method does everything.
|
||||
* 2: carry on as normal.
|
||||
* 3: ASN1 method sets algorithm identifiers: just sign.
|
||||
*/
|
||||
if (rv <= 0)
|
||||
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
|
||||
if (rv <= 1)
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
rv = 2;
|
||||
if (pkey->ameth->item_sign) {
|
||||
rv = pkey->ameth->item_sign(ctx, it, asn, algor1, algor2, signature);
|
||||
if (rv == 1)
|
||||
outl = signature->length;
|
||||
/*-
|
||||
* Return value meanings:
|
||||
* <=0: error.
|
||||
* 1: method does everything.
|
||||
* 2: carry on as normal.
|
||||
* 3: ASN1 method sets algorithm identifiers: just sign.
|
||||
*/
|
||||
if (rv <= 0)
|
||||
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
|
||||
if (rv <= 1)
|
||||
goto err;
|
||||
} else
|
||||
rv = 2;
|
||||
|
||||
if (rv == 2)
|
||||
{
|
||||
if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE)
|
||||
{
|
||||
if (!pkey->ameth ||
|
||||
!OBJ_find_sigid_by_algs(&signid,
|
||||
EVP_MD_nid(type),
|
||||
pkey->ameth->pkey_id))
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
|
||||
ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
else
|
||||
signid = type->pkey_type;
|
||||
if (rv == 2) {
|
||||
if (type->flags & EVP_MD_FLAG_PKEY_METHOD_SIGNATURE) {
|
||||
if (!pkey->ameth ||
|
||||
!OBJ_find_sigid_by_algs(&signid,
|
||||
EVP_MD_nid(type),
|
||||
pkey->ameth->pkey_id)) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,
|
||||
ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED);
|
||||
return 0;
|
||||
}
|
||||
} else
|
||||
signid = type->pkey_type;
|
||||
|
||||
if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
|
||||
paramtype = V_ASN1_NULL;
|
||||
else
|
||||
paramtype = V_ASN1_UNDEF;
|
||||
if (pkey->ameth->pkey_flags & ASN1_PKEY_SIGPARAM_NULL)
|
||||
paramtype = V_ASN1_NULL;
|
||||
else
|
||||
paramtype = V_ASN1_UNDEF;
|
||||
|
||||
if (algor1)
|
||||
X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
|
||||
if (algor2)
|
||||
X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
|
||||
if (algor1)
|
||||
X509_ALGOR_set0(algor1, OBJ_nid2obj(signid), paramtype, NULL);
|
||||
if (algor2)
|
||||
X509_ALGOR_set0(algor2, OBJ_nid2obj(signid), paramtype, NULL);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
inl=ASN1_item_i2d(asn,&buf_in, it);
|
||||
outll=outl=EVP_PKEY_size(pkey);
|
||||
buf_out=OPENSSL_malloc((unsigned int)outl);
|
||||
if ((buf_in == NULL) || (buf_out == NULL))
|
||||
{
|
||||
outl=0;
|
||||
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
inl = ASN1_item_i2d(asn, &buf_in, it);
|
||||
outll = outl = EVP_PKEY_size(pkey);
|
||||
buf_out = OPENSSL_malloc((unsigned int)outl);
|
||||
if ((buf_in == NULL) || (buf_out == NULL)) {
|
||||
outl = 0;
|
||||
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
|
||||
|| !EVP_DigestSignFinal(ctx, buf_out, &outl))
|
||||
{
|
||||
outl=0;
|
||||
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX,ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (signature->data != NULL) OPENSSL_free(signature->data);
|
||||
signature->data=buf_out;
|
||||
buf_out=NULL;
|
||||
signature->length=outl;
|
||||
/* In the interests of compatibility, I'll make sure that
|
||||
* the bit string has a 'not-used bits' value of 0
|
||||
*/
|
||||
signature->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
|
||||
signature->flags|=ASN1_STRING_FLAG_BITS_LEFT;
|
||||
err:
|
||||
EVP_MD_CTX_cleanup(ctx);
|
||||
if (buf_in != NULL)
|
||||
{ OPENSSL_cleanse((char *)buf_in,(unsigned int)inl); OPENSSL_free(buf_in); }
|
||||
if (buf_out != NULL)
|
||||
{ OPENSSL_cleanse((char *)buf_out,outll); OPENSSL_free(buf_out); }
|
||||
return(outl);
|
||||
}
|
||||
if (!EVP_DigestSignUpdate(ctx, buf_in, inl)
|
||||
|| !EVP_DigestSignFinal(ctx, buf_out, &outl)) {
|
||||
outl = 0;
|
||||
ASN1err(ASN1_F_ASN1_ITEM_SIGN_CTX, ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (signature->data != NULL)
|
||||
OPENSSL_free(signature->data);
|
||||
signature->data = buf_out;
|
||||
buf_out = NULL;
|
||||
signature->length = outl;
|
||||
/*
|
||||
* In the interests of compatibility, I'll make sure that the bit string
|
||||
* has a 'not-used bits' value of 0
|
||||
*/
|
||||
signature->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
|
||||
signature->flags |= ASN1_STRING_FLAG_BITS_LEFT;
|
||||
err:
|
||||
EVP_MD_CTX_cleanup(ctx);
|
||||
if (buf_in != NULL) {
|
||||
OPENSSL_cleanse((char *)buf_in, (unsigned int)inl);
|
||||
OPENSSL_free(buf_in);
|
||||
}
|
||||
if (buf_out != NULL) {
|
||||
OPENSSL_cleanse((char *)buf_out, outll);
|
||||
OPENSSL_free(buf_out);
|
||||
}
|
||||
return (outl);
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
/* a_strnid.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -62,31 +63,31 @@
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/objects.h>
|
||||
|
||||
|
||||
static STACK_OF(ASN1_STRING_TABLE) *stable = NULL;
|
||||
static void st_free(ASN1_STRING_TABLE *tbl);
|
||||
static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
|
||||
const ASN1_STRING_TABLE * const *b);
|
||||
static int sk_table_cmp(const ASN1_STRING_TABLE *const *a,
|
||||
const ASN1_STRING_TABLE *const *b);
|
||||
|
||||
|
||||
/* This is the global mask for the mbstring functions: this is use to
|
||||
* mask out certain types (such as BMPString and UTF8String) because
|
||||
* certain software (e.g. Netscape) has problems with them.
|
||||
/*
|
||||
* This is the global mask for the mbstring functions: this is use to mask
|
||||
* out certain types (such as BMPString and UTF8String) because certain
|
||||
* software (e.g. Netscape) has problems with them.
|
||||
*/
|
||||
|
||||
static unsigned long global_mask = B_ASN1_UTF8STRING;
|
||||
|
||||
void ASN1_STRING_set_default_mask(unsigned long mask)
|
||||
{
|
||||
global_mask = mask;
|
||||
global_mask = mask;
|
||||
}
|
||||
|
||||
unsigned long ASN1_STRING_get_default_mask(void)
|
||||
{
|
||||
return global_mask;
|
||||
return global_mask;
|
||||
}
|
||||
|
||||
/* This function sets the default to various "flavours" of configuration.
|
||||
/*-
|
||||
* This function sets the default to various "flavours" of configuration.
|
||||
* based on an ASCII string. Currently this is:
|
||||
* MASK:XXXX : a numerical mask value.
|
||||
* nobmp : Don't use BMPStrings (just Printable, T61).
|
||||
@ -97,160 +98,185 @@ unsigned long ASN1_STRING_get_default_mask(void)
|
||||
|
||||
int ASN1_STRING_set_default_mask_asc(const char *p)
|
||||
{
|
||||
unsigned long mask;
|
||||
char *end;
|
||||
if(!strncmp(p, "MASK:", 5)) {
|
||||
if(!p[5]) return 0;
|
||||
mask = strtoul(p + 5, &end, 0);
|
||||
if(*end) return 0;
|
||||
} else if(!strcmp(p, "nombstr"))
|
||||
mask = ~((unsigned long)(B_ASN1_BMPSTRING|B_ASN1_UTF8STRING));
|
||||
else if(!strcmp(p, "pkix"))
|
||||
mask = ~((unsigned long)B_ASN1_T61STRING);
|
||||
else if(!strcmp(p, "utf8only")) mask = B_ASN1_UTF8STRING;
|
||||
else if(!strcmp(p, "default"))
|
||||
mask = 0xFFFFFFFFL;
|
||||
else return 0;
|
||||
ASN1_STRING_set_default_mask(mask);
|
||||
return 1;
|
||||
unsigned long mask;
|
||||
char *end;
|
||||
if (!strncmp(p, "MASK:", 5)) {
|
||||
if (!p[5])
|
||||
return 0;
|
||||
mask = strtoul(p + 5, &end, 0);
|
||||
if (*end)
|
||||
return 0;
|
||||
} else if (!strcmp(p, "nombstr"))
|
||||
mask = ~((unsigned long)(B_ASN1_BMPSTRING | B_ASN1_UTF8STRING));
|
||||
else if (!strcmp(p, "pkix"))
|
||||
mask = ~((unsigned long)B_ASN1_T61STRING);
|
||||
else if (!strcmp(p, "utf8only"))
|
||||
mask = B_ASN1_UTF8STRING;
|
||||
else if (!strcmp(p, "default"))
|
||||
mask = 0xFFFFFFFFL;
|
||||
else
|
||||
return 0;
|
||||
ASN1_STRING_set_default_mask(mask);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* The following function generates an ASN1_STRING based on limits in a table.
|
||||
* Frequently the types and length of an ASN1_STRING are restricted by a
|
||||
* corresponding OID. For example certificates and certificate requests.
|
||||
/*
|
||||
* The following function generates an ASN1_STRING based on limits in a
|
||||
* table. Frequently the types and length of an ASN1_STRING are restricted by
|
||||
* a corresponding OID. For example certificates and certificate requests.
|
||||
*/
|
||||
|
||||
ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out, const unsigned char *in,
|
||||
int inlen, int inform, int nid)
|
||||
ASN1_STRING *ASN1_STRING_set_by_NID(ASN1_STRING **out,
|
||||
const unsigned char *in, int inlen,
|
||||
int inform, int nid)
|
||||
{
|
||||
ASN1_STRING_TABLE *tbl;
|
||||
ASN1_STRING *str = NULL;
|
||||
unsigned long mask;
|
||||
int ret;
|
||||
if(!out) out = &str;
|
||||
tbl = ASN1_STRING_TABLE_get(nid);
|
||||
if(tbl) {
|
||||
mask = tbl->mask;
|
||||
if(!(tbl->flags & STABLE_NO_MASK)) mask &= global_mask;
|
||||
ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
|
||||
tbl->minsize, tbl->maxsize);
|
||||
} else ret = ASN1_mbstring_copy(out, in, inlen, inform, DIRSTRING_TYPE & global_mask);
|
||||
if(ret <= 0) return NULL;
|
||||
return *out;
|
||||
ASN1_STRING_TABLE *tbl;
|
||||
ASN1_STRING *str = NULL;
|
||||
unsigned long mask;
|
||||
int ret;
|
||||
if (!out)
|
||||
out = &str;
|
||||
tbl = ASN1_STRING_TABLE_get(nid);
|
||||
if (tbl) {
|
||||
mask = tbl->mask;
|
||||
if (!(tbl->flags & STABLE_NO_MASK))
|
||||
mask &= global_mask;
|
||||
ret = ASN1_mbstring_ncopy(out, in, inlen, inform, mask,
|
||||
tbl->minsize, tbl->maxsize);
|
||||
} else
|
||||
ret =
|
||||
ASN1_mbstring_copy(out, in, inlen, inform,
|
||||
DIRSTRING_TYPE & global_mask);
|
||||
if (ret <= 0)
|
||||
return NULL;
|
||||
return *out;
|
||||
}
|
||||
|
||||
/* Now the tables and helper functions for the string table:
|
||||
/*
|
||||
* Now the tables and helper functions for the string table:
|
||||
*/
|
||||
|
||||
/* size limits: this stuff is taken straight from RFC3280 */
|
||||
|
||||
#define ub_name 32768
|
||||
#define ub_common_name 64
|
||||
#define ub_locality_name 128
|
||||
#define ub_state_name 128
|
||||
#define ub_organization_name 64
|
||||
#define ub_organization_unit_name 64
|
||||
#define ub_title 64
|
||||
#define ub_email_address 128
|
||||
#define ub_serial_number 64
|
||||
|
||||
#define ub_name 32768
|
||||
#define ub_common_name 64
|
||||
#define ub_locality_name 128
|
||||
#define ub_state_name 128
|
||||
#define ub_organization_name 64
|
||||
#define ub_organization_unit_name 64
|
||||
#define ub_title 64
|
||||
#define ub_email_address 128
|
||||
#define ub_serial_number 64
|
||||
|
||||
/* This table must be kept in NID order */
|
||||
|
||||
static const ASN1_STRING_TABLE tbl_standard[] = {
|
||||
{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
|
||||
{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
|
||||
{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
|
||||
{NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
|
||||
{NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
|
||||
{NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE, 0},
|
||||
{NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING, STABLE_NO_MASK},
|
||||
{NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
|
||||
{NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
|
||||
{NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
|
||||
{NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
|
||||
{NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
|
||||
{NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
|
||||
{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
|
||||
{NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
|
||||
{NID_commonName, 1, ub_common_name, DIRSTRING_TYPE, 0},
|
||||
{NID_countryName, 2, 2, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
|
||||
{NID_localityName, 1, ub_locality_name, DIRSTRING_TYPE, 0},
|
||||
{NID_stateOrProvinceName, 1, ub_state_name, DIRSTRING_TYPE, 0},
|
||||
{NID_organizationName, 1, ub_organization_name, DIRSTRING_TYPE, 0},
|
||||
{NID_organizationalUnitName, 1, ub_organization_unit_name, DIRSTRING_TYPE,
|
||||
0},
|
||||
{NID_pkcs9_emailAddress, 1, ub_email_address, B_ASN1_IA5STRING,
|
||||
STABLE_NO_MASK},
|
||||
{NID_pkcs9_unstructuredName, 1, -1, PKCS9STRING_TYPE, 0},
|
||||
{NID_pkcs9_challengePassword, 1, -1, PKCS9STRING_TYPE, 0},
|
||||
{NID_pkcs9_unstructuredAddress, 1, -1, DIRSTRING_TYPE, 0},
|
||||
{NID_givenName, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_surname, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_initials, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_serialNumber, 1, ub_serial_number, B_ASN1_PRINTABLESTRING,
|
||||
STABLE_NO_MASK},
|
||||
{NID_friendlyName, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK},
|
||||
{NID_name, 1, ub_name, DIRSTRING_TYPE, 0},
|
||||
{NID_dnQualifier, -1, -1, B_ASN1_PRINTABLESTRING, STABLE_NO_MASK},
|
||||
{NID_domainComponent, 1, -1, B_ASN1_IA5STRING, STABLE_NO_MASK},
|
||||
{NID_ms_csp_name, -1, -1, B_ASN1_BMPSTRING, STABLE_NO_MASK}
|
||||
};
|
||||
|
||||
static int sk_table_cmp(const ASN1_STRING_TABLE * const *a,
|
||||
const ASN1_STRING_TABLE * const *b)
|
||||
static int sk_table_cmp(const ASN1_STRING_TABLE *const *a,
|
||||
const ASN1_STRING_TABLE *const *b)
|
||||
{
|
||||
return (*a)->nid - (*b)->nid;
|
||||
return (*a)->nid - (*b)->nid;
|
||||
}
|
||||
|
||||
DECLARE_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
|
||||
|
||||
static int table_cmp(const ASN1_STRING_TABLE *a, const ASN1_STRING_TABLE *b)
|
||||
{
|
||||
return a->nid - b->nid;
|
||||
return a->nid - b->nid;
|
||||
}
|
||||
|
||||
IMPLEMENT_OBJ_BSEARCH_CMP_FN(ASN1_STRING_TABLE, ASN1_STRING_TABLE, table);
|
||||
|
||||
ASN1_STRING_TABLE *ASN1_STRING_TABLE_get(int nid)
|
||||
{
|
||||
int idx;
|
||||
ASN1_STRING_TABLE *ttmp;
|
||||
ASN1_STRING_TABLE fnd;
|
||||
fnd.nid = nid;
|
||||
ttmp = OBJ_bsearch_table(&fnd, tbl_standard,
|
||||
sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE));
|
||||
if(ttmp) return ttmp;
|
||||
if(!stable) return NULL;
|
||||
idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
|
||||
if(idx < 0) return NULL;
|
||||
return sk_ASN1_STRING_TABLE_value(stable, idx);
|
||||
int idx;
|
||||
ASN1_STRING_TABLE *ttmp;
|
||||
ASN1_STRING_TABLE fnd;
|
||||
fnd.nid = nid;
|
||||
ttmp = OBJ_bsearch_table(&fnd, tbl_standard,
|
||||
sizeof(tbl_standard) /
|
||||
sizeof(ASN1_STRING_TABLE));
|
||||
if (ttmp)
|
||||
return ttmp;
|
||||
if (!stable)
|
||||
return NULL;
|
||||
idx = sk_ASN1_STRING_TABLE_find(stable, &fnd);
|
||||
if (idx < 0)
|
||||
return NULL;
|
||||
return sk_ASN1_STRING_TABLE_value(stable, idx);
|
||||
}
|
||||
|
||||
|
||||
int ASN1_STRING_TABLE_add(int nid,
|
||||
long minsize, long maxsize, unsigned long mask,
|
||||
unsigned long flags)
|
||||
long minsize, long maxsize, unsigned long mask,
|
||||
unsigned long flags)
|
||||
{
|
||||
ASN1_STRING_TABLE *tmp;
|
||||
char new_nid = 0;
|
||||
flags &= ~STABLE_FLAGS_MALLOC;
|
||||
if(!stable) stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
|
||||
if(!stable) {
|
||||
ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if(!(tmp = ASN1_STRING_TABLE_get(nid))) {
|
||||
tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
|
||||
if(!tmp) {
|
||||
ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD,
|
||||
ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
tmp->flags = flags | STABLE_FLAGS_MALLOC;
|
||||
tmp->nid = nid;
|
||||
new_nid = 1;
|
||||
} else tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
|
||||
if(minsize != -1) tmp->minsize = minsize;
|
||||
if(maxsize != -1) tmp->maxsize = maxsize;
|
||||
tmp->mask = mask;
|
||||
if(new_nid) sk_ASN1_STRING_TABLE_push(stable, tmp);
|
||||
return 1;
|
||||
ASN1_STRING_TABLE *tmp;
|
||||
char new_nid = 0;
|
||||
flags &= ~STABLE_FLAGS_MALLOC;
|
||||
if (!stable)
|
||||
stable = sk_ASN1_STRING_TABLE_new(sk_table_cmp);
|
||||
if (!stable) {
|
||||
ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
if (!(tmp = ASN1_STRING_TABLE_get(nid))) {
|
||||
tmp = OPENSSL_malloc(sizeof(ASN1_STRING_TABLE));
|
||||
if (!tmp) {
|
||||
ASN1err(ASN1_F_ASN1_STRING_TABLE_ADD, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
tmp->flags = flags | STABLE_FLAGS_MALLOC;
|
||||
tmp->nid = nid;
|
||||
new_nid = 1;
|
||||
} else
|
||||
tmp->flags = (tmp->flags & STABLE_FLAGS_MALLOC) | flags;
|
||||
if (minsize != -1)
|
||||
tmp->minsize = minsize;
|
||||
if (maxsize != -1)
|
||||
tmp->maxsize = maxsize;
|
||||
tmp->mask = mask;
|
||||
if (new_nid)
|
||||
sk_ASN1_STRING_TABLE_push(stable, tmp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void ASN1_STRING_TABLE_cleanup(void)
|
||||
{
|
||||
STACK_OF(ASN1_STRING_TABLE) *tmp;
|
||||
tmp = stable;
|
||||
if(!tmp) return;
|
||||
stable = NULL;
|
||||
sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
|
||||
STACK_OF(ASN1_STRING_TABLE) *tmp;
|
||||
tmp = stable;
|
||||
if (!tmp)
|
||||
return;
|
||||
stable = NULL;
|
||||
sk_ASN1_STRING_TABLE_pop_free(tmp, st_free);
|
||||
}
|
||||
|
||||
static void st_free(ASN1_STRING_TABLE *tbl)
|
||||
{
|
||||
if(tbl->flags & STABLE_FLAGS_MALLOC) OPENSSL_free(tbl);
|
||||
if (tbl->flags & STABLE_FLAGS_MALLOC)
|
||||
OPENSSL_free(tbl);
|
||||
}
|
||||
|
||||
|
||||
@ -260,30 +286,27 @@ IMPLEMENT_STACK_OF(ASN1_STRING_TABLE)
|
||||
|
||||
main()
|
||||
{
|
||||
ASN1_STRING_TABLE *tmp;
|
||||
int i, last_nid = -1;
|
||||
ASN1_STRING_TABLE *tmp;
|
||||
int i, last_nid = -1;
|
||||
|
||||
for (tmp = tbl_standard, i = 0;
|
||||
i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
|
||||
{
|
||||
if (tmp->nid < last_nid)
|
||||
{
|
||||
last_nid = 0;
|
||||
break;
|
||||
}
|
||||
last_nid = tmp->nid;
|
||||
}
|
||||
for (tmp = tbl_standard, i = 0;
|
||||
i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++) {
|
||||
if (tmp->nid < last_nid) {
|
||||
last_nid = 0;
|
||||
break;
|
||||
}
|
||||
last_nid = tmp->nid;
|
||||
}
|
||||
|
||||
if (last_nid != 0)
|
||||
{
|
||||
printf("Table order OK\n");
|
||||
exit(0);
|
||||
}
|
||||
if (last_nid != 0) {
|
||||
printf("Table order OK\n");
|
||||
exit(0);
|
||||
}
|
||||
|
||||
for (tmp = tbl_standard, i = 0;
|
||||
i < sizeof(tbl_standard)/sizeof(ASN1_STRING_TABLE); i++, tmp++)
|
||||
printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
|
||||
OBJ_nid2ln(tmp->nid));
|
||||
for (tmp = tbl_standard, i = 0;
|
||||
i < sizeof(tbl_standard) / sizeof(ASN1_STRING_TABLE); i++, tmp++)
|
||||
printf("Index %d, NID %d, Name=%s\n", i, tmp->nid,
|
||||
OBJ_nid2ln(tmp->nid));
|
||||
|
||||
}
|
||||
|
||||
|
||||
@ -7,7 +7,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -53,8 +53,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
/* This is an implementation of the ASN1 Time structure which is:
|
||||
/*-
|
||||
* This is an implementation of the ASN1 Time structure which is:
|
||||
* Time ::= CHOICE {
|
||||
* utcTime UTCTime,
|
||||
* generalTime GeneralizedTime }
|
||||
@ -73,126 +73,126 @@ IMPLEMENT_ASN1_FUNCTIONS(ASN1_TIME)
|
||||
|
||||
#if 0
|
||||
int i2d_ASN1_TIME(ASN1_TIME *a, unsigned char **pp)
|
||||
{
|
||||
#ifdef CHARSET_EBCDIC
|
||||
/* KLUDGE! We convert to ascii before writing DER */
|
||||
char tmp[24];
|
||||
ASN1_STRING tmpstr;
|
||||
{
|
||||
# ifdef CHARSET_EBCDIC
|
||||
/* KLUDGE! We convert to ascii before writing DER */
|
||||
char tmp[24];
|
||||
ASN1_STRING tmpstr;
|
||||
|
||||
if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) {
|
||||
int len;
|
||||
if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME) {
|
||||
int len;
|
||||
|
||||
tmpstr = *(ASN1_STRING *)a;
|
||||
len = tmpstr.length;
|
||||
ebcdic2ascii(tmp, tmpstr.data, (len >= sizeof tmp) ? sizeof tmp : len);
|
||||
tmpstr.data = tmp;
|
||||
a = (ASN1_GENERALIZEDTIME *) &tmpstr;
|
||||
}
|
||||
tmpstr = *(ASN1_STRING *)a;
|
||||
len = tmpstr.length;
|
||||
ebcdic2ascii(tmp, tmpstr.data,
|
||||
(len >= sizeof tmp) ? sizeof tmp : len);
|
||||
tmpstr.data = tmp;
|
||||
a = (ASN1_GENERALIZEDTIME *)&tmpstr;
|
||||
}
|
||||
# endif
|
||||
if (a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
|
||||
return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
|
||||
a->type, V_ASN1_UNIVERSAL));
|
||||
ASN1err(ASN1_F_I2D_ASN1_TIME, ASN1_R_EXPECTING_A_TIME);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
if(a->type == V_ASN1_UTCTIME || a->type == V_ASN1_GENERALIZEDTIME)
|
||||
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
|
||||
a->type ,V_ASN1_UNIVERSAL));
|
||||
ASN1err(ASN1_F_I2D_ASN1_TIME,ASN1_R_EXPECTING_A_TIME);
|
||||
return -1;
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
ASN1_TIME *ASN1_TIME_set(ASN1_TIME *s, time_t t)
|
||||
{
|
||||
return ASN1_TIME_adj(s, t, 0, 0);
|
||||
}
|
||||
{
|
||||
return ASN1_TIME_adj(s, t, 0, 0);
|
||||
}
|
||||
|
||||
ASN1_TIME *ASN1_TIME_adj(ASN1_TIME *s, time_t t,
|
||||
int offset_day, long offset_sec)
|
||||
{
|
||||
struct tm *ts;
|
||||
struct tm data;
|
||||
int offset_day, long offset_sec)
|
||||
{
|
||||
struct tm *ts;
|
||||
struct tm data;
|
||||
|
||||
ts=OPENSSL_gmtime(&t,&data);
|
||||
if (ts == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME);
|
||||
return NULL;
|
||||
}
|
||||
if (offset_day || offset_sec)
|
||||
{
|
||||
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
|
||||
return NULL;
|
||||
}
|
||||
if((ts->tm_year >= 50) && (ts->tm_year < 150))
|
||||
return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
|
||||
return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
|
||||
}
|
||||
ts = OPENSSL_gmtime(&t, &data);
|
||||
if (ts == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_TIME_ADJ, ASN1_R_ERROR_GETTING_TIME);
|
||||
return NULL;
|
||||
}
|
||||
if (offset_day || offset_sec) {
|
||||
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
|
||||
return NULL;
|
||||
}
|
||||
if ((ts->tm_year >= 50) && (ts->tm_year < 150))
|
||||
return ASN1_UTCTIME_adj(s, t, offset_day, offset_sec);
|
||||
return ASN1_GENERALIZEDTIME_adj(s, t, offset_day, offset_sec);
|
||||
}
|
||||
|
||||
int ASN1_TIME_check(ASN1_TIME *t)
|
||||
{
|
||||
if (t->type == V_ASN1_GENERALIZEDTIME)
|
||||
return ASN1_GENERALIZEDTIME_check(t);
|
||||
else if (t->type == V_ASN1_UTCTIME)
|
||||
return ASN1_UTCTIME_check(t);
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
if (t->type == V_ASN1_GENERALIZEDTIME)
|
||||
return ASN1_GENERALIZEDTIME_check(t);
|
||||
else if (t->type == V_ASN1_UTCTIME)
|
||||
return ASN1_UTCTIME_check(t);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Convert an ASN1_TIME structure to GeneralizedTime */
|
||||
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t, ASN1_GENERALIZEDTIME **out)
|
||||
{
|
||||
ASN1_GENERALIZEDTIME *ret;
|
||||
char *str;
|
||||
int newlen;
|
||||
ASN1_GENERALIZEDTIME *ASN1_TIME_to_generalizedtime(ASN1_TIME *t,
|
||||
ASN1_GENERALIZEDTIME **out)
|
||||
{
|
||||
ASN1_GENERALIZEDTIME *ret;
|
||||
char *str;
|
||||
int newlen;
|
||||
|
||||
if (!ASN1_TIME_check(t)) return NULL;
|
||||
if (!ASN1_TIME_check(t))
|
||||
return NULL;
|
||||
|
||||
if (!out || !*out)
|
||||
{
|
||||
if (!(ret = ASN1_GENERALIZEDTIME_new ()))
|
||||
return NULL;
|
||||
if (out) *out = ret;
|
||||
}
|
||||
else ret = *out;
|
||||
if (!out || !*out) {
|
||||
if (!(ret = ASN1_GENERALIZEDTIME_new()))
|
||||
return NULL;
|
||||
if (out)
|
||||
*out = ret;
|
||||
} else
|
||||
ret = *out;
|
||||
|
||||
/* If already GeneralizedTime just copy across */
|
||||
if (t->type == V_ASN1_GENERALIZEDTIME)
|
||||
{
|
||||
if(!ASN1_STRING_set(ret, t->data, t->length))
|
||||
return NULL;
|
||||
return ret;
|
||||
}
|
||||
/* If already GeneralizedTime just copy across */
|
||||
if (t->type == V_ASN1_GENERALIZEDTIME) {
|
||||
if (!ASN1_STRING_set(ret, t->data, t->length))
|
||||
return NULL;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* grow the string */
|
||||
if (!ASN1_STRING_set(ret, NULL, t->length + 2))
|
||||
return NULL;
|
||||
/* ASN1_STRING_set() allocated 'len + 1' bytes. */
|
||||
newlen = t->length + 2 + 1;
|
||||
str = (char *)ret->data;
|
||||
/* Work out the century and prepend */
|
||||
if (t->data[0] >= '5') BUF_strlcpy(str, "19", newlen);
|
||||
else BUF_strlcpy(str, "20", newlen);
|
||||
/* grow the string */
|
||||
if (!ASN1_STRING_set(ret, NULL, t->length + 2))
|
||||
return NULL;
|
||||
/* ASN1_STRING_set() allocated 'len + 1' bytes. */
|
||||
newlen = t->length + 2 + 1;
|
||||
str = (char *)ret->data;
|
||||
/* Work out the century and prepend */
|
||||
if (t->data[0] >= '5')
|
||||
BUF_strlcpy(str, "19", newlen);
|
||||
else
|
||||
BUF_strlcpy(str, "20", newlen);
|
||||
|
||||
BUF_strlcat(str, (char *)t->data, newlen);
|
||||
BUF_strlcat(str, (char *)t->data, newlen);
|
||||
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ASN1_TIME_set_string(ASN1_TIME *s, const char *str)
|
||||
{
|
||||
ASN1_TIME t;
|
||||
{
|
||||
ASN1_TIME t;
|
||||
|
||||
t.length = strlen(str);
|
||||
t.data = (unsigned char *)str;
|
||||
t.flags = 0;
|
||||
|
||||
t.type = V_ASN1_UTCTIME;
|
||||
t.length = strlen(str);
|
||||
t.data = (unsigned char *)str;
|
||||
t.flags = 0;
|
||||
|
||||
if (!ASN1_TIME_check(&t))
|
||||
{
|
||||
t.type = V_ASN1_GENERALIZEDTIME;
|
||||
if (!ASN1_TIME_check(&t))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
|
||||
return 0;
|
||||
t.type = V_ASN1_UTCTIME;
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (!ASN1_TIME_check(&t)) {
|
||||
t.type = V_ASN1_GENERALIZEDTIME;
|
||||
if (!ASN1_TIME_check(&t))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (s && !ASN1_STRING_copy((ASN1_STRING *)s, (ASN1_STRING *)&t))
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,98 +62,96 @@
|
||||
#include <openssl/objects.h>
|
||||
|
||||
int ASN1_TYPE_get(ASN1_TYPE *a)
|
||||
{
|
||||
if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
|
||||
return(a->type);
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
{
|
||||
if ((a->value.ptr != NULL) || (a->type == V_ASN1_NULL))
|
||||
return (a->type);
|
||||
else
|
||||
return (0);
|
||||
}
|
||||
|
||||
void ASN1_TYPE_set(ASN1_TYPE *a, int type, void *value)
|
||||
{
|
||||
if (a->value.ptr != NULL)
|
||||
{
|
||||
ASN1_TYPE **tmp_a = &a;
|
||||
ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
|
||||
}
|
||||
a->type=type;
|
||||
if (type == V_ASN1_BOOLEAN)
|
||||
a->value.boolean = value ? 0xff : 0;
|
||||
else
|
||||
a->value.ptr=value;
|
||||
}
|
||||
{
|
||||
if (a->value.ptr != NULL) {
|
||||
ASN1_TYPE **tmp_a = &a;
|
||||
ASN1_primitive_free((ASN1_VALUE **)tmp_a, NULL);
|
||||
}
|
||||
a->type = type;
|
||||
if (type == V_ASN1_BOOLEAN)
|
||||
a->value.boolean = value ? 0xff : 0;
|
||||
else
|
||||
a->value.ptr = value;
|
||||
}
|
||||
|
||||
int ASN1_TYPE_set1(ASN1_TYPE *a, int type, const void *value)
|
||||
{
|
||||
if (!value || (type == V_ASN1_BOOLEAN))
|
||||
{
|
||||
void *p = (void *)value;
|
||||
ASN1_TYPE_set(a, type, p);
|
||||
}
|
||||
else if (type == V_ASN1_OBJECT)
|
||||
{
|
||||
ASN1_OBJECT *odup;
|
||||
odup = OBJ_dup(value);
|
||||
if (!odup)
|
||||
return 0;
|
||||
ASN1_TYPE_set(a, type, odup);
|
||||
}
|
||||
else
|
||||
{
|
||||
ASN1_STRING *sdup;
|
||||
sdup = ASN1_STRING_dup(value);
|
||||
if (!sdup)
|
||||
return 0;
|
||||
ASN1_TYPE_set(a, type, sdup);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
if (!value || (type == V_ASN1_BOOLEAN)) {
|
||||
void *p = (void *)value;
|
||||
ASN1_TYPE_set(a, type, p);
|
||||
} else if (type == V_ASN1_OBJECT) {
|
||||
ASN1_OBJECT *odup;
|
||||
odup = OBJ_dup(value);
|
||||
if (!odup)
|
||||
return 0;
|
||||
ASN1_TYPE_set(a, type, odup);
|
||||
} else {
|
||||
ASN1_STRING *sdup;
|
||||
sdup = ASN1_STRING_dup(value);
|
||||
if (!sdup)
|
||||
return 0;
|
||||
ASN1_TYPE_set(a, type, sdup);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
IMPLEMENT_STACK_OF(ASN1_TYPE)
|
||||
|
||||
IMPLEMENT_ASN1_SET_OF(ASN1_TYPE)
|
||||
|
||||
/* Returns 0 if they are equal, != 0 otherwise. */
|
||||
int ASN1_TYPE_cmp(ASN1_TYPE *a, ASN1_TYPE *b)
|
||||
{
|
||||
int result = -1;
|
||||
int ASN1_TYPE_cmp(const ASN1_TYPE *a, const ASN1_TYPE *b)
|
||||
{
|
||||
int result = -1;
|
||||
|
||||
if (!a || !b || a->type != b->type) return -1;
|
||||
if (!a || !b || a->type != b->type)
|
||||
return -1;
|
||||
|
||||
switch (a->type)
|
||||
{
|
||||
case V_ASN1_OBJECT:
|
||||
result = OBJ_cmp(a->value.object, b->value.object);
|
||||
break;
|
||||
case V_ASN1_NULL:
|
||||
result = 0; /* They do not have content. */
|
||||
break;
|
||||
case V_ASN1_INTEGER:
|
||||
case V_ASN1_NEG_INTEGER:
|
||||
case V_ASN1_ENUMERATED:
|
||||
case V_ASN1_NEG_ENUMERATED:
|
||||
case V_ASN1_BIT_STRING:
|
||||
case V_ASN1_OCTET_STRING:
|
||||
case V_ASN1_SEQUENCE:
|
||||
case V_ASN1_SET:
|
||||
case V_ASN1_NUMERICSTRING:
|
||||
case V_ASN1_PRINTABLESTRING:
|
||||
case V_ASN1_T61STRING:
|
||||
case V_ASN1_VIDEOTEXSTRING:
|
||||
case V_ASN1_IA5STRING:
|
||||
case V_ASN1_UTCTIME:
|
||||
case V_ASN1_GENERALIZEDTIME:
|
||||
case V_ASN1_GRAPHICSTRING:
|
||||
case V_ASN1_VISIBLESTRING:
|
||||
case V_ASN1_GENERALSTRING:
|
||||
case V_ASN1_UNIVERSALSTRING:
|
||||
case V_ASN1_BMPSTRING:
|
||||
case V_ASN1_UTF8STRING:
|
||||
case V_ASN1_OTHER:
|
||||
default:
|
||||
result = ASN1_STRING_cmp((ASN1_STRING *) a->value.ptr,
|
||||
(ASN1_STRING *) b->value.ptr);
|
||||
break;
|
||||
}
|
||||
switch (a->type) {
|
||||
case V_ASN1_OBJECT:
|
||||
result = OBJ_cmp(a->value.object, b->value.object);
|
||||
break;
|
||||
case V_ASN1_BOOLEAN:
|
||||
result = a->value.boolean - b->value.boolean;
|
||||
break;
|
||||
case V_ASN1_NULL:
|
||||
result = 0; /* They do not have content. */
|
||||
break;
|
||||
case V_ASN1_INTEGER:
|
||||
case V_ASN1_NEG_INTEGER:
|
||||
case V_ASN1_ENUMERATED:
|
||||
case V_ASN1_NEG_ENUMERATED:
|
||||
case V_ASN1_BIT_STRING:
|
||||
case V_ASN1_OCTET_STRING:
|
||||
case V_ASN1_SEQUENCE:
|
||||
case V_ASN1_SET:
|
||||
case V_ASN1_NUMERICSTRING:
|
||||
case V_ASN1_PRINTABLESTRING:
|
||||
case V_ASN1_T61STRING:
|
||||
case V_ASN1_VIDEOTEXSTRING:
|
||||
case V_ASN1_IA5STRING:
|
||||
case V_ASN1_UTCTIME:
|
||||
case V_ASN1_GENERALIZEDTIME:
|
||||
case V_ASN1_GRAPHICSTRING:
|
||||
case V_ASN1_VISIBLESTRING:
|
||||
case V_ASN1_GENERALSTRING:
|
||||
case V_ASN1_UNIVERSALSTRING:
|
||||
case V_ASN1_BMPSTRING:
|
||||
case V_ASN1_UTF8STRING:
|
||||
case V_ASN1_OTHER:
|
||||
default:
|
||||
result = ASN1_STRING_cmp((ASN1_STRING *)a->value.ptr,
|
||||
(ASN1_STRING *)b->value.ptr);
|
||||
break;
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -64,255 +64,267 @@
|
||||
|
||||
#if 0
|
||||
int i2d_ASN1_UTCTIME(ASN1_UTCTIME *a, unsigned char **pp)
|
||||
{
|
||||
#ifndef CHARSET_EBCDIC
|
||||
return(i2d_ASN1_bytes((ASN1_STRING *)a,pp,
|
||||
V_ASN1_UTCTIME,V_ASN1_UNIVERSAL));
|
||||
#else
|
||||
/* KLUDGE! We convert to ascii before writing DER */
|
||||
int len;
|
||||
char tmp[24];
|
||||
ASN1_STRING x = *(ASN1_STRING *)a;
|
||||
|
||||
len = x.length;
|
||||
ebcdic2ascii(tmp, x.data, (len >= sizeof tmp) ? sizeof tmp : len);
|
||||
x.data = tmp;
|
||||
return i2d_ASN1_bytes(&x, pp, V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
|
||||
#endif
|
||||
}
|
||||
{
|
||||
# ifndef CHARSET_EBCDIC
|
||||
return (i2d_ASN1_bytes((ASN1_STRING *)a, pp,
|
||||
V_ASN1_UTCTIME, V_ASN1_UNIVERSAL));
|
||||
# else
|
||||
/* KLUDGE! We convert to ascii before writing DER */
|
||||
int len;
|
||||
char tmp[24];
|
||||
ASN1_STRING x = *(ASN1_STRING *)a;
|
||||
|
||||
len = x.length;
|
||||
ebcdic2ascii(tmp, x.data, (len >= sizeof tmp) ? sizeof tmp : len);
|
||||
x.data = tmp;
|
||||
return i2d_ASN1_bytes(&x, pp, V_ASN1_UTCTIME, V_ASN1_UNIVERSAL);
|
||||
# endif
|
||||
}
|
||||
|
||||
ASN1_UTCTIME *d2i_ASN1_UTCTIME(ASN1_UTCTIME **a, unsigned char **pp,
|
||||
long length)
|
||||
{
|
||||
ASN1_UTCTIME *ret=NULL;
|
||||
long length)
|
||||
{
|
||||
ASN1_UTCTIME *ret = NULL;
|
||||
|
||||
ret=(ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a,pp,length,
|
||||
V_ASN1_UTCTIME,V_ASN1_UNIVERSAL);
|
||||
if (ret == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_ASN1_UTCTIME,ERR_R_NESTED_ASN1_ERROR);
|
||||
return(NULL);
|
||||
}
|
||||
#ifdef CHARSET_EBCDIC
|
||||
ascii2ebcdic(ret->data, ret->data, ret->length);
|
||||
#endif
|
||||
if (!ASN1_UTCTIME_check(ret))
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_ASN1_UTCTIME,ASN1_R_INVALID_TIME_FORMAT);
|
||||
goto err;
|
||||
}
|
||||
ret = (ASN1_UTCTIME *)d2i_ASN1_bytes((ASN1_STRING **)a, pp, length,
|
||||
V_ASN1_UTCTIME, V_ASN1_UNIVERSAL);
|
||||
if (ret == NULL) {
|
||||
ASN1err(ASN1_F_D2I_ASN1_UTCTIME, ERR_R_NESTED_ASN1_ERROR);
|
||||
return (NULL);
|
||||
}
|
||||
# ifdef CHARSET_EBCDIC
|
||||
ascii2ebcdic(ret->data, ret->data, ret->length);
|
||||
# endif
|
||||
if (!ASN1_UTCTIME_check(ret)) {
|
||||
ASN1err(ASN1_F_D2I_ASN1_UTCTIME, ASN1_R_INVALID_TIME_FORMAT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
return(ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_UTCTIME_free(ret);
|
||||
return(NULL);
|
||||
}
|
||||
return (ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
M_ASN1_UTCTIME_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int ASN1_UTCTIME_check(ASN1_UTCTIME *d)
|
||||
{
|
||||
static const int min[8]={ 0, 1, 1, 0, 0, 0, 0, 0};
|
||||
static const int max[8]={99,12,31,23,59,59,12,59};
|
||||
char *a;
|
||||
int n,i,l,o;
|
||||
{
|
||||
static const int min[8] = { 0, 1, 1, 0, 0, 0, 0, 0 };
|
||||
static const int max[8] = { 99, 12, 31, 23, 59, 59, 12, 59 };
|
||||
char *a;
|
||||
int n, i, l, o;
|
||||
|
||||
if (d->type != V_ASN1_UTCTIME) return(0);
|
||||
l=d->length;
|
||||
a=(char *)d->data;
|
||||
o=0;
|
||||
if (d->type != V_ASN1_UTCTIME)
|
||||
return (0);
|
||||
l = d->length;
|
||||
a = (char *)d->data;
|
||||
o = 0;
|
||||
|
||||
if (l < 11) goto err;
|
||||
for (i=0; i<6; i++)
|
||||
{
|
||||
if ((i == 5) && ((a[o] == 'Z') ||
|
||||
(a[o] == '+') || (a[o] == '-')))
|
||||
{ i++; break; }
|
||||
if ((a[o] < '0') || (a[o] > '9')) goto err;
|
||||
n= a[o]-'0';
|
||||
if (++o > l) goto err;
|
||||
if (l < 11)
|
||||
goto err;
|
||||
for (i = 0; i < 6; i++) {
|
||||
if ((i == 5) && ((a[o] == 'Z') || (a[o] == '+') || (a[o] == '-'))) {
|
||||
i++;
|
||||
break;
|
||||
}
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = a[o] - '0';
|
||||
if (++o > l)
|
||||
goto err;
|
||||
|
||||
if ((a[o] < '0') || (a[o] > '9')) goto err;
|
||||
n=(n*10)+ a[o]-'0';
|
||||
if (++o > l) goto err;
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = (n * 10) + a[o] - '0';
|
||||
if (++o > l)
|
||||
goto err;
|
||||
|
||||
if ((n < min[i]) || (n > max[i])) goto err;
|
||||
}
|
||||
if (a[o] == 'Z')
|
||||
o++;
|
||||
else if ((a[o] == '+') || (a[o] == '-'))
|
||||
{
|
||||
o++;
|
||||
if (o+4 > l) goto err;
|
||||
for (i=6; i<8; i++)
|
||||
{
|
||||
if ((a[o] < '0') || (a[o] > '9')) goto err;
|
||||
n= a[o]-'0';
|
||||
o++;
|
||||
if ((a[o] < '0') || (a[o] > '9')) goto err;
|
||||
n=(n*10)+ a[o]-'0';
|
||||
if ((n < min[i]) || (n > max[i])) goto err;
|
||||
o++;
|
||||
}
|
||||
}
|
||||
return(o == l);
|
||||
err:
|
||||
return(0);
|
||||
}
|
||||
if ((n < min[i]) || (n > max[i]))
|
||||
goto err;
|
||||
}
|
||||
if (a[o] == 'Z')
|
||||
o++;
|
||||
else if ((a[o] == '+') || (a[o] == '-')) {
|
||||
o++;
|
||||
if (o + 4 > l)
|
||||
goto err;
|
||||
for (i = 6; i < 8; i++) {
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = a[o] - '0';
|
||||
o++;
|
||||
if ((a[o] < '0') || (a[o] > '9'))
|
||||
goto err;
|
||||
n = (n * 10) + a[o] - '0';
|
||||
if ((n < min[i]) || (n > max[i]))
|
||||
goto err;
|
||||
o++;
|
||||
}
|
||||
}
|
||||
return (o == l);
|
||||
err:
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ASN1_UTCTIME_set_string(ASN1_UTCTIME *s, const char *str)
|
||||
{
|
||||
ASN1_UTCTIME t;
|
||||
{
|
||||
ASN1_UTCTIME t;
|
||||
|
||||
t.type=V_ASN1_UTCTIME;
|
||||
t.length=strlen(str);
|
||||
t.data=(unsigned char *)str;
|
||||
if (ASN1_UTCTIME_check(&t))
|
||||
{
|
||||
if (s != NULL)
|
||||
{
|
||||
if (!ASN1_STRING_set((ASN1_STRING *)s,
|
||||
(unsigned char *)str,t.length))
|
||||
return 0;
|
||||
s->type = V_ASN1_UTCTIME;
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
else
|
||||
return(0);
|
||||
}
|
||||
t.type = V_ASN1_UTCTIME;
|
||||
t.length = strlen(str);
|
||||
t.data = (unsigned char *)str;
|
||||
if (ASN1_UTCTIME_check(&t)) {
|
||||
if (s != NULL) {
|
||||
if (!ASN1_STRING_set((ASN1_STRING *)s,
|
||||
(unsigned char *)str, t.length))
|
||||
return 0;
|
||||
s->type = V_ASN1_UTCTIME;
|
||||
}
|
||||
return (1);
|
||||
} else
|
||||
return (0);
|
||||
}
|
||||
|
||||
ASN1_UTCTIME *ASN1_UTCTIME_set(ASN1_UTCTIME *s, time_t t)
|
||||
{
|
||||
return ASN1_UTCTIME_adj(s, t, 0, 0);
|
||||
}
|
||||
{
|
||||
return ASN1_UTCTIME_adj(s, t, 0, 0);
|
||||
}
|
||||
|
||||
ASN1_UTCTIME *ASN1_UTCTIME_adj(ASN1_UTCTIME *s, time_t t,
|
||||
int offset_day, long offset_sec)
|
||||
{
|
||||
char *p;
|
||||
struct tm *ts;
|
||||
struct tm data;
|
||||
size_t len = 20;
|
||||
int offset_day, long offset_sec)
|
||||
{
|
||||
char *p;
|
||||
struct tm *ts;
|
||||
struct tm data;
|
||||
size_t len = 20;
|
||||
int free_s = 0;
|
||||
|
||||
if (s == NULL)
|
||||
s=M_ASN1_UTCTIME_new();
|
||||
if (s == NULL)
|
||||
return(NULL);
|
||||
if (s == NULL) {
|
||||
free_s = 1;
|
||||
s = M_ASN1_UTCTIME_new();
|
||||
}
|
||||
if (s == NULL)
|
||||
goto err;
|
||||
|
||||
ts=OPENSSL_gmtime(&t, &data);
|
||||
if (ts == NULL)
|
||||
return(NULL);
|
||||
ts = OPENSSL_gmtime(&t, &data);
|
||||
if (ts == NULL)
|
||||
goto err;
|
||||
|
||||
if (offset_day || offset_sec)
|
||||
{
|
||||
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
|
||||
return NULL;
|
||||
}
|
||||
if (offset_day || offset_sec) {
|
||||
if (!OPENSSL_gmtime_adj(ts, offset_day, offset_sec))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if((ts->tm_year < 50) || (ts->tm_year >= 150))
|
||||
return NULL;
|
||||
if ((ts->tm_year < 50) || (ts->tm_year >= 150))
|
||||
goto err;
|
||||
|
||||
p=(char *)s->data;
|
||||
if ((p == NULL) || ((size_t)s->length < len))
|
||||
{
|
||||
p=OPENSSL_malloc(len);
|
||||
if (p == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_UTCTIME_ADJ,ERR_R_MALLOC_FAILURE);
|
||||
return(NULL);
|
||||
}
|
||||
if (s->data != NULL)
|
||||
OPENSSL_free(s->data);
|
||||
s->data=(unsigned char *)p;
|
||||
}
|
||||
p = (char *)s->data;
|
||||
if ((p == NULL) || ((size_t)s->length < len)) {
|
||||
p = OPENSSL_malloc(len);
|
||||
if (p == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_UTCTIME_ADJ, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (s->data != NULL)
|
||||
OPENSSL_free(s->data);
|
||||
s->data = (unsigned char *)p;
|
||||
}
|
||||
|
||||
BIO_snprintf(p,len,"%02d%02d%02d%02d%02d%02dZ",ts->tm_year%100,
|
||||
ts->tm_mon+1,ts->tm_mday,ts->tm_hour,ts->tm_min,ts->tm_sec);
|
||||
s->length=strlen(p);
|
||||
s->type=V_ASN1_UTCTIME;
|
||||
BIO_snprintf(p, len, "%02d%02d%02d%02d%02d%02dZ", ts->tm_year % 100,
|
||||
ts->tm_mon + 1, ts->tm_mday, ts->tm_hour, ts->tm_min,
|
||||
ts->tm_sec);
|
||||
s->length = strlen(p);
|
||||
s->type = V_ASN1_UTCTIME;
|
||||
#ifdef CHARSET_EBCDIC_not
|
||||
ebcdic2ascii(s->data, s->data, s->length);
|
||||
ebcdic2ascii(s->data, s->data, s->length);
|
||||
#endif
|
||||
return(s);
|
||||
}
|
||||
|
||||
return (s);
|
||||
err:
|
||||
if (free_s && s)
|
||||
M_ASN1_UTCTIME_free(s);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int ASN1_UTCTIME_cmp_time_t(const ASN1_UTCTIME *s, time_t t)
|
||||
{
|
||||
struct tm *tm;
|
||||
struct tm data;
|
||||
int offset;
|
||||
int year;
|
||||
{
|
||||
struct tm *tm;
|
||||
struct tm data;
|
||||
int offset;
|
||||
int year;
|
||||
|
||||
#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
|
||||
|
||||
if (s->data[12] == 'Z')
|
||||
offset=0;
|
||||
else
|
||||
{
|
||||
offset = g2(s->data+13)*60+g2(s->data+15);
|
||||
if (s->data[12] == '-')
|
||||
offset = -offset;
|
||||
}
|
||||
if (s->data[12] == 'Z')
|
||||
offset = 0;
|
||||
else {
|
||||
offset = g2(s->data + 13) * 60 + g2(s->data + 15);
|
||||
if (s->data[12] == '-')
|
||||
offset = -offset;
|
||||
}
|
||||
|
||||
t -= offset*60; /* FIXME: may overflow in extreme cases */
|
||||
t -= offset * 60; /* FIXME: may overflow in extreme cases */
|
||||
|
||||
tm = OPENSSL_gmtime(&t, &data);
|
||||
/*
|
||||
* NB: -1, 0, 1 already valid return values so use -2 to indicate error.
|
||||
*/
|
||||
if (tm == NULL)
|
||||
return -2;
|
||||
|
||||
tm = OPENSSL_gmtime(&t, &data);
|
||||
|
||||
#define return_cmp(a,b) if ((a)<(b)) return -1; else if ((a)>(b)) return 1
|
||||
year = g2(s->data);
|
||||
if (year < 50)
|
||||
year += 100;
|
||||
return_cmp(year, tm->tm_year);
|
||||
return_cmp(g2(s->data+2) - 1, tm->tm_mon);
|
||||
return_cmp(g2(s->data+4), tm->tm_mday);
|
||||
return_cmp(g2(s->data+6), tm->tm_hour);
|
||||
return_cmp(g2(s->data+8), tm->tm_min);
|
||||
return_cmp(g2(s->data+10), tm->tm_sec);
|
||||
year = g2(s->data);
|
||||
if (year < 50)
|
||||
year += 100;
|
||||
return_cmp(year, tm->tm_year);
|
||||
return_cmp(g2(s->data + 2) - 1, tm->tm_mon);
|
||||
return_cmp(g2(s->data + 4), tm->tm_mday);
|
||||
return_cmp(g2(s->data + 6), tm->tm_hour);
|
||||
return_cmp(g2(s->data + 8), tm->tm_min);
|
||||
return_cmp(g2(s->data + 10), tm->tm_sec);
|
||||
#undef g2
|
||||
#undef return_cmp
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#if 0
|
||||
time_t ASN1_UTCTIME_get(const ASN1_UTCTIME *s)
|
||||
{
|
||||
struct tm tm;
|
||||
int offset;
|
||||
{
|
||||
struct tm tm;
|
||||
int offset;
|
||||
|
||||
memset(&tm,'\0',sizeof tm);
|
||||
memset(&tm, '\0', sizeof tm);
|
||||
|
||||
#define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
|
||||
tm.tm_year=g2(s->data);
|
||||
if(tm.tm_year < 50)
|
||||
tm.tm_year+=100;
|
||||
tm.tm_mon=g2(s->data+2)-1;
|
||||
tm.tm_mday=g2(s->data+4);
|
||||
tm.tm_hour=g2(s->data+6);
|
||||
tm.tm_min=g2(s->data+8);
|
||||
tm.tm_sec=g2(s->data+10);
|
||||
if(s->data[12] == 'Z')
|
||||
offset=0;
|
||||
else
|
||||
{
|
||||
offset=g2(s->data+13)*60+g2(s->data+15);
|
||||
if(s->data[12] == '-')
|
||||
offset= -offset;
|
||||
}
|
||||
#undef g2
|
||||
# define g2(p) (((p)[0]-'0')*10+(p)[1]-'0')
|
||||
tm.tm_year = g2(s->data);
|
||||
if (tm.tm_year < 50)
|
||||
tm.tm_year += 100;
|
||||
tm.tm_mon = g2(s->data + 2) - 1;
|
||||
tm.tm_mday = g2(s->data + 4);
|
||||
tm.tm_hour = g2(s->data + 6);
|
||||
tm.tm_min = g2(s->data + 8);
|
||||
tm.tm_sec = g2(s->data + 10);
|
||||
if (s->data[12] == 'Z')
|
||||
offset = 0;
|
||||
else {
|
||||
offset = g2(s->data + 13) * 60 + g2(s->data + 15);
|
||||
if (s->data[12] == '-')
|
||||
offset = -offset;
|
||||
}
|
||||
# undef g2
|
||||
|
||||
return mktime(&tm)-offset*60; /* FIXME: mktime assumes the current timezone
|
||||
* instead of UTC, and unless we rewrite OpenSSL
|
||||
* in Lisp we cannot locally change the timezone
|
||||
* without possibly interfering with other parts
|
||||
* of the program. timegm, which uses UTC, is
|
||||
* non-standard.
|
||||
* Also time_t is inappropriate for general
|
||||
* UTC times because it may a 32 bit type. */
|
||||
}
|
||||
/*
|
||||
* FIXME: mktime assumes the current timezone
|
||||
* instead of UTC, and unless we rewrite OpenSSL
|
||||
* in Lisp we cannot locally change the timezone
|
||||
* without possibly interfering with other parts
|
||||
* of the program. timegm, which uses UTC, is
|
||||
* non-standard.
|
||||
* Also time_t is inappropriate for general
|
||||
* UTC times because it may a 32 bit type.
|
||||
*/
|
||||
return mktime(&tm) - offset * 60;
|
||||
}
|
||||
#endif
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -60,10 +60,10 @@
|
||||
#include "cryptlib.h"
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
|
||||
/* UTF8 utilities */
|
||||
|
||||
/* This parses a UTF8 string one character at a time. It is passed a pointer
|
||||
/*-
|
||||
* This parses a UTF8 string one character at a time. It is passed a pointer
|
||||
* to the string and the length of the string. It sets 'value' to the value of
|
||||
* the current character. It returns the number of characters read or a
|
||||
* negative error code:
|
||||
@ -75,137 +75,163 @@
|
||||
|
||||
int UTF8_getc(const unsigned char *str, int len, unsigned long *val)
|
||||
{
|
||||
const unsigned char *p;
|
||||
unsigned long value;
|
||||
int ret;
|
||||
if(len <= 0) return 0;
|
||||
p = str;
|
||||
const unsigned char *p;
|
||||
unsigned long value;
|
||||
int ret;
|
||||
if (len <= 0)
|
||||
return 0;
|
||||
p = str;
|
||||
|
||||
/* Check syntax and work out the encoded value (if correct) */
|
||||
if((*p & 0x80) == 0) {
|
||||
value = *p++ & 0x7f;
|
||||
ret = 1;
|
||||
} else if((*p & 0xe0) == 0xc0) {
|
||||
if(len < 2) return -1;
|
||||
if((p[1] & 0xc0) != 0x80) return -3;
|
||||
value = (*p++ & 0x1f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
if(value < 0x80) return -4;
|
||||
ret = 2;
|
||||
} else if((*p & 0xf0) == 0xe0) {
|
||||
if(len < 3) return -1;
|
||||
if( ((p[1] & 0xc0) != 0x80)
|
||||
|| ((p[2] & 0xc0) != 0x80) ) return -3;
|
||||
value = (*p++ & 0xf) << 12;
|
||||
value |= (*p++ & 0x3f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
if(value < 0x800) return -4;
|
||||
ret = 3;
|
||||
} else if((*p & 0xf8) == 0xf0) {
|
||||
if(len < 4) return -1;
|
||||
if( ((p[1] & 0xc0) != 0x80)
|
||||
|| ((p[2] & 0xc0) != 0x80)
|
||||
|| ((p[3] & 0xc0) != 0x80) ) return -3;
|
||||
value = ((unsigned long)(*p++ & 0x7)) << 18;
|
||||
value |= (*p++ & 0x3f) << 12;
|
||||
value |= (*p++ & 0x3f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
if(value < 0x10000) return -4;
|
||||
ret = 4;
|
||||
} else if((*p & 0xfc) == 0xf8) {
|
||||
if(len < 5) return -1;
|
||||
if( ((p[1] & 0xc0) != 0x80)
|
||||
|| ((p[2] & 0xc0) != 0x80)
|
||||
|| ((p[3] & 0xc0) != 0x80)
|
||||
|| ((p[4] & 0xc0) != 0x80) ) return -3;
|
||||
value = ((unsigned long)(*p++ & 0x3)) << 24;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 18;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 12;
|
||||
value |= (*p++ & 0x3f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
if(value < 0x200000) return -4;
|
||||
ret = 5;
|
||||
} else if((*p & 0xfe) == 0xfc) {
|
||||
if(len < 6) return -1;
|
||||
if( ((p[1] & 0xc0) != 0x80)
|
||||
|| ((p[2] & 0xc0) != 0x80)
|
||||
|| ((p[3] & 0xc0) != 0x80)
|
||||
|| ((p[4] & 0xc0) != 0x80)
|
||||
|| ((p[5] & 0xc0) != 0x80) ) return -3;
|
||||
value = ((unsigned long)(*p++ & 0x1)) << 30;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 24;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 18;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 12;
|
||||
value |= (*p++ & 0x3f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
if(value < 0x4000000) return -4;
|
||||
ret = 6;
|
||||
} else return -2;
|
||||
*val = value;
|
||||
return ret;
|
||||
/* Check syntax and work out the encoded value (if correct) */
|
||||
if ((*p & 0x80) == 0) {
|
||||
value = *p++ & 0x7f;
|
||||
ret = 1;
|
||||
} else if ((*p & 0xe0) == 0xc0) {
|
||||
if (len < 2)
|
||||
return -1;
|
||||
if ((p[1] & 0xc0) != 0x80)
|
||||
return -3;
|
||||
value = (*p++ & 0x1f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
if (value < 0x80)
|
||||
return -4;
|
||||
ret = 2;
|
||||
} else if ((*p & 0xf0) == 0xe0) {
|
||||
if (len < 3)
|
||||
return -1;
|
||||
if (((p[1] & 0xc0) != 0x80)
|
||||
|| ((p[2] & 0xc0) != 0x80))
|
||||
return -3;
|
||||
value = (*p++ & 0xf) << 12;
|
||||
value |= (*p++ & 0x3f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
if (value < 0x800)
|
||||
return -4;
|
||||
ret = 3;
|
||||
} else if ((*p & 0xf8) == 0xf0) {
|
||||
if (len < 4)
|
||||
return -1;
|
||||
if (((p[1] & 0xc0) != 0x80)
|
||||
|| ((p[2] & 0xc0) != 0x80)
|
||||
|| ((p[3] & 0xc0) != 0x80))
|
||||
return -3;
|
||||
value = ((unsigned long)(*p++ & 0x7)) << 18;
|
||||
value |= (*p++ & 0x3f) << 12;
|
||||
value |= (*p++ & 0x3f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
if (value < 0x10000)
|
||||
return -4;
|
||||
ret = 4;
|
||||
} else if ((*p & 0xfc) == 0xf8) {
|
||||
if (len < 5)
|
||||
return -1;
|
||||
if (((p[1] & 0xc0) != 0x80)
|
||||
|| ((p[2] & 0xc0) != 0x80)
|
||||
|| ((p[3] & 0xc0) != 0x80)
|
||||
|| ((p[4] & 0xc0) != 0x80))
|
||||
return -3;
|
||||
value = ((unsigned long)(*p++ & 0x3)) << 24;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 18;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 12;
|
||||
value |= (*p++ & 0x3f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
if (value < 0x200000)
|
||||
return -4;
|
||||
ret = 5;
|
||||
} else if ((*p & 0xfe) == 0xfc) {
|
||||
if (len < 6)
|
||||
return -1;
|
||||
if (((p[1] & 0xc0) != 0x80)
|
||||
|| ((p[2] & 0xc0) != 0x80)
|
||||
|| ((p[3] & 0xc0) != 0x80)
|
||||
|| ((p[4] & 0xc0) != 0x80)
|
||||
|| ((p[5] & 0xc0) != 0x80))
|
||||
return -3;
|
||||
value = ((unsigned long)(*p++ & 0x1)) << 30;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 24;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 18;
|
||||
value |= ((unsigned long)(*p++ & 0x3f)) << 12;
|
||||
value |= (*p++ & 0x3f) << 6;
|
||||
value |= *p++ & 0x3f;
|
||||
if (value < 0x4000000)
|
||||
return -4;
|
||||
ret = 6;
|
||||
} else
|
||||
return -2;
|
||||
*val = value;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* This takes a character 'value' and writes the UTF8 encoded value in
|
||||
* 'str' where 'str' is a buffer containing 'len' characters. Returns
|
||||
* the number of characters written or -1 if 'len' is too small. 'str' can
|
||||
* be set to NULL in which case it just returns the number of characters.
|
||||
* It will need at most 6 characters.
|
||||
/*
|
||||
* This takes a character 'value' and writes the UTF8 encoded value in 'str'
|
||||
* where 'str' is a buffer containing 'len' characters. Returns the number of
|
||||
* characters written or -1 if 'len' is too small. 'str' can be set to NULL
|
||||
* in which case it just returns the number of characters. It will need at
|
||||
* most 6 characters.
|
||||
*/
|
||||
|
||||
int UTF8_putc(unsigned char *str, int len, unsigned long value)
|
||||
{
|
||||
if(!str) len = 6; /* Maximum we will need */
|
||||
else if(len <= 0) return -1;
|
||||
if(value < 0x80) {
|
||||
if(str) *str = (unsigned char)value;
|
||||
return 1;
|
||||
}
|
||||
if(value < 0x800) {
|
||||
if(len < 2) return -1;
|
||||
if(str) {
|
||||
*str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
|
||||
*str = (unsigned char)((value & 0x3f) | 0x80);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
if(value < 0x10000) {
|
||||
if(len < 3) return -1;
|
||||
if(str) {
|
||||
*str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
|
||||
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
|
||||
*str = (unsigned char)((value & 0x3f) | 0x80);
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
if(value < 0x200000) {
|
||||
if(len < 4) return -1;
|
||||
if(str) {
|
||||
*str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
|
||||
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
|
||||
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
|
||||
*str = (unsigned char)((value & 0x3f) | 0x80);
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
if(value < 0x4000000) {
|
||||
if(len < 5) return -1;
|
||||
if(str) {
|
||||
*str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
|
||||
*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
|
||||
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
|
||||
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
|
||||
*str = (unsigned char)((value & 0x3f) | 0x80);
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
if(len < 6) return -1;
|
||||
if(str) {
|
||||
*str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
|
||||
*str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
|
||||
*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
|
||||
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
|
||||
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
|
||||
*str = (unsigned char)((value & 0x3f) | 0x80);
|
||||
}
|
||||
return 6;
|
||||
if (!str)
|
||||
len = 6; /* Maximum we will need */
|
||||
else if (len <= 0)
|
||||
return -1;
|
||||
if (value < 0x80) {
|
||||
if (str)
|
||||
*str = (unsigned char)value;
|
||||
return 1;
|
||||
}
|
||||
if (value < 0x800) {
|
||||
if (len < 2)
|
||||
return -1;
|
||||
if (str) {
|
||||
*str++ = (unsigned char)(((value >> 6) & 0x1f) | 0xc0);
|
||||
*str = (unsigned char)((value & 0x3f) | 0x80);
|
||||
}
|
||||
return 2;
|
||||
}
|
||||
if (value < 0x10000) {
|
||||
if (len < 3)
|
||||
return -1;
|
||||
if (str) {
|
||||
*str++ = (unsigned char)(((value >> 12) & 0xf) | 0xe0);
|
||||
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
|
||||
*str = (unsigned char)((value & 0x3f) | 0x80);
|
||||
}
|
||||
return 3;
|
||||
}
|
||||
if (value < 0x200000) {
|
||||
if (len < 4)
|
||||
return -1;
|
||||
if (str) {
|
||||
*str++ = (unsigned char)(((value >> 18) & 0x7) | 0xf0);
|
||||
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
|
||||
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
|
||||
*str = (unsigned char)((value & 0x3f) | 0x80);
|
||||
}
|
||||
return 4;
|
||||
}
|
||||
if (value < 0x4000000) {
|
||||
if (len < 5)
|
||||
return -1;
|
||||
if (str) {
|
||||
*str++ = (unsigned char)(((value >> 24) & 0x3) | 0xf8);
|
||||
*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
|
||||
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
|
||||
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
|
||||
*str = (unsigned char)((value & 0x3f) | 0x80);
|
||||
}
|
||||
return 5;
|
||||
}
|
||||
if (len < 6)
|
||||
return -1;
|
||||
if (str) {
|
||||
*str++ = (unsigned char)(((value >> 30) & 0x1) | 0xfc);
|
||||
*str++ = (unsigned char)(((value >> 24) & 0x3f) | 0x80);
|
||||
*str++ = (unsigned char)(((value >> 18) & 0x3f) | 0x80);
|
||||
*str++ = (unsigned char)(((value >> 12) & 0x3f) | 0x80);
|
||||
*str++ = (unsigned char)(((value >> 6) & 0x3f) | 0x80);
|
||||
*str = (unsigned char)((value & 0x3f) | 0x80);
|
||||
}
|
||||
return 6;
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -75,160 +75,157 @@
|
||||
#ifndef NO_ASN1_OLD
|
||||
|
||||
int ASN1_verify(i2d_of_void *i2d, X509_ALGOR *a, ASN1_BIT_STRING *signature,
|
||||
char *data, EVP_PKEY *pkey)
|
||||
{
|
||||
EVP_MD_CTX ctx;
|
||||
const EVP_MD *type;
|
||||
unsigned char *p,*buf_in=NULL;
|
||||
int ret= -1,i,inl;
|
||||
char *data, EVP_PKEY *pkey)
|
||||
{
|
||||
EVP_MD_CTX ctx;
|
||||
const EVP_MD *type;
|
||||
unsigned char *p, *buf_in = NULL;
|
||||
int ret = -1, i, inl;
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
i=OBJ_obj2nid(a->algorithm);
|
||||
type=EVP_get_digestbyname(OBJ_nid2sn(i));
|
||||
if (type == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
|
||||
goto err;
|
||||
}
|
||||
|
||||
inl=i2d(data,NULL);
|
||||
buf_in=OPENSSL_malloc((unsigned int)inl);
|
||||
if (buf_in == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
p=buf_in;
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
i = OBJ_obj2nid(a->algorithm);
|
||||
type = EVP_get_digestbyname(OBJ_nid2sn(i));
|
||||
if (type == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
|
||||
goto err;
|
||||
}
|
||||
|
||||
i2d(data,&p);
|
||||
if (!EVP_VerifyInit_ex(&ctx,type, NULL)
|
||||
|| !EVP_VerifyUpdate(&ctx,(unsigned char *)buf_in,inl))
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB);
|
||||
ret=0;
|
||||
goto err;
|
||||
}
|
||||
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
|
||||
ASN1err(ASN1_F_ASN1_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
|
||||
goto err;
|
||||
}
|
||||
|
||||
OPENSSL_cleanse(buf_in,(unsigned int)inl);
|
||||
OPENSSL_free(buf_in);
|
||||
inl = i2d(data, NULL);
|
||||
buf_in = OPENSSL_malloc((unsigned int)inl);
|
||||
if (buf_in == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
p = buf_in;
|
||||
|
||||
if (EVP_VerifyFinal(&ctx,(unsigned char *)signature->data,
|
||||
(unsigned int)signature->length,pkey) <= 0)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_VERIFY,ERR_R_EVP_LIB);
|
||||
ret=0;
|
||||
goto err;
|
||||
}
|
||||
/* we don't need to zero the 'ctx' because we just checked
|
||||
* public information */
|
||||
/* memset(&ctx,0,sizeof(ctx)); */
|
||||
ret=1;
|
||||
err:
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
return(ret);
|
||||
}
|
||||
i2d(data, &p);
|
||||
if (!EVP_VerifyInit_ex(&ctx, type, NULL)
|
||||
|| !EVP_VerifyUpdate(&ctx, (unsigned char *)buf_in, inl)) {
|
||||
ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
|
||||
ret = 0;
|
||||
goto err;
|
||||
}
|
||||
|
||||
OPENSSL_cleanse(buf_in, (unsigned int)inl);
|
||||
OPENSSL_free(buf_in);
|
||||
|
||||
if (EVP_VerifyFinal(&ctx, (unsigned char *)signature->data,
|
||||
(unsigned int)signature->length, pkey) <= 0) {
|
||||
ASN1err(ASN1_F_ASN1_VERIFY, ERR_R_EVP_LIB);
|
||||
ret = 0;
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* we don't need to zero the 'ctx' because we just checked public
|
||||
* information
|
||||
*/
|
||||
/* memset(&ctx,0,sizeof(ctx)); */
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
|
||||
int ASN1_item_verify(const ASN1_ITEM *it, X509_ALGOR *a,
|
||||
ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
|
||||
{
|
||||
EVP_MD_CTX ctx;
|
||||
unsigned char *buf_in=NULL;
|
||||
int ret= -1,inl;
|
||||
ASN1_BIT_STRING *signature, void *asn, EVP_PKEY *pkey)
|
||||
{
|
||||
EVP_MD_CTX ctx;
|
||||
unsigned char *buf_in = NULL;
|
||||
int ret = -1, inl;
|
||||
|
||||
int mdnid, pknid;
|
||||
int mdnid, pknid;
|
||||
|
||||
if (!pkey)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
if (!pkey) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_PASSED_NULL_PARAMETER);
|
||||
return -1;
|
||||
}
|
||||
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
if (signature->type == V_ASN1_BIT_STRING && signature->flags & 0x7) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_INVALID_BIT_STRING_BITS_LEFT);
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* Convert signature OID into digest and public key OIDs */
|
||||
if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid))
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
|
||||
goto err;
|
||||
}
|
||||
if (mdnid == NID_undef)
|
||||
{
|
||||
if (!pkey->ameth || !pkey->ameth->item_verify)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
|
||||
goto err;
|
||||
}
|
||||
ret = pkey->ameth->item_verify(&ctx, it, asn, a,
|
||||
signature, pkey);
|
||||
/* Return value of 2 means carry on, anything else means we
|
||||
* exit straight away: either a fatal error of the underlying
|
||||
* verification routine handles all verification.
|
||||
*/
|
||||
if (ret != 2)
|
||||
goto err;
|
||||
ret = -1;
|
||||
}
|
||||
else
|
||||
{
|
||||
const EVP_MD *type;
|
||||
type=EVP_get_digestbynid(mdnid);
|
||||
if (type == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
|
||||
goto err;
|
||||
}
|
||||
EVP_MD_CTX_init(&ctx);
|
||||
|
||||
/* Check public key OID matches public key type */
|
||||
if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ASN1_R_WRONG_PUBLIC_KEY_TYPE);
|
||||
goto err;
|
||||
}
|
||||
/* Convert signature OID into digest and public key OIDs */
|
||||
if (!OBJ_find_sigid_algs(OBJ_obj2nid(a->algorithm), &mdnid, &pknid)) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
|
||||
goto err;
|
||||
}
|
||||
if (mdnid == NID_undef) {
|
||||
if (!pkey->ameth || !pkey->ameth->item_verify) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
|
||||
ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM);
|
||||
goto err;
|
||||
}
|
||||
ret = pkey->ameth->item_verify(&ctx, it, asn, a, signature, pkey);
|
||||
/*
|
||||
* Return value of 2 means carry on, anything else means we exit
|
||||
* straight away: either a fatal error of the underlying verification
|
||||
* routine handles all verification.
|
||||
*/
|
||||
if (ret != 2)
|
||||
goto err;
|
||||
ret = -1;
|
||||
} else {
|
||||
const EVP_MD *type;
|
||||
type = EVP_get_digestbynid(mdnid);
|
||||
if (type == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,
|
||||
ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey))
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
|
||||
ret=0;
|
||||
goto err;
|
||||
}
|
||||
/* Check public key OID matches public key type */
|
||||
if (EVP_PKEY_type(pknid) != pkey->ameth->pkey_id) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ASN1_R_WRONG_PUBLIC_KEY_TYPE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
}
|
||||
if (!EVP_DigestVerifyInit(&ctx, NULL, type, NULL, pkey)) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
|
||||
ret = 0;
|
||||
goto err;
|
||||
}
|
||||
|
||||
inl = ASN1_item_i2d(asn, &buf_in, it);
|
||||
|
||||
if (buf_in == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
if (!EVP_DigestVerifyUpdate(&ctx,buf_in,inl))
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
|
||||
ret=0;
|
||||
goto err;
|
||||
}
|
||||
inl = ASN1_item_i2d(asn, &buf_in, it);
|
||||
|
||||
OPENSSL_cleanse(buf_in,(unsigned int)inl);
|
||||
OPENSSL_free(buf_in);
|
||||
if (buf_in == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (EVP_DigestVerifyFinal(&ctx,signature->data,
|
||||
(size_t)signature->length) <= 0)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY,ERR_R_EVP_LIB);
|
||||
ret=0;
|
||||
goto err;
|
||||
}
|
||||
/* we don't need to zero the 'ctx' because we just checked
|
||||
* public information */
|
||||
/* memset(&ctx,0,sizeof(ctx)); */
|
||||
ret=1;
|
||||
err:
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
return(ret);
|
||||
}
|
||||
if (!EVP_DigestVerifyUpdate(&ctx, buf_in, inl)) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
|
||||
ret = 0;
|
||||
goto err;
|
||||
}
|
||||
|
||||
OPENSSL_cleanse(buf_in, (unsigned int)inl);
|
||||
OPENSSL_free(buf_in);
|
||||
|
||||
if (EVP_DigestVerifyFinal(&ctx, signature->data,
|
||||
(size_t)signature->length) <= 0) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_VERIFY, ERR_R_EVP_LIB);
|
||||
ret = 0;
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* we don't need to zero the 'ctx' because we just checked public
|
||||
* information
|
||||
*/
|
||||
/* memset(&ctx,0,sizeof(ctx)); */
|
||||
ret = 1;
|
||||
err:
|
||||
EVP_MD_CTX_cleanup(&ctx);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2006.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
@ -9,7 +10,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -60,7 +61,7 @@
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/x509.h>
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
# include <openssl/engine.h>
|
||||
#endif
|
||||
#include "asn1_locl.h"
|
||||
|
||||
@ -72,389 +73,390 @@ extern const EVP_PKEY_ASN1_METHOD hmac_asn1_meth;
|
||||
extern const EVP_PKEY_ASN1_METHOD cmac_asn1_meth;
|
||||
|
||||
/* Keep this sorted in type order !! */
|
||||
static const EVP_PKEY_ASN1_METHOD *standard_methods[] =
|
||||
{
|
||||
static const EVP_PKEY_ASN1_METHOD *standard_methods[] = {
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
&rsa_asn1_meths[0],
|
||||
&rsa_asn1_meths[1],
|
||||
&rsa_asn1_meths[0],
|
||||
&rsa_asn1_meths[1],
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DH
|
||||
&dh_asn1_meth,
|
||||
&dh_asn1_meth,
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
&dsa_asn1_meths[0],
|
||||
&dsa_asn1_meths[1],
|
||||
&dsa_asn1_meths[2],
|
||||
&dsa_asn1_meths[3],
|
||||
&dsa_asn1_meths[4],
|
||||
&dsa_asn1_meths[0],
|
||||
&dsa_asn1_meths[1],
|
||||
&dsa_asn1_meths[2],
|
||||
&dsa_asn1_meths[3],
|
||||
&dsa_asn1_meths[4],
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
&eckey_asn1_meth,
|
||||
&eckey_asn1_meth,
|
||||
#endif
|
||||
&hmac_asn1_meth,
|
||||
&cmac_asn1_meth
|
||||
};
|
||||
&hmac_asn1_meth,
|
||||
&cmac_asn1_meth
|
||||
};
|
||||
|
||||
typedef int sk_cmp_fn_type(const char * const *a, const char * const *b);
|
||||
typedef int sk_cmp_fn_type(const char *const *a, const char *const *b);
|
||||
DECLARE_STACK_OF(EVP_PKEY_ASN1_METHOD)
|
||||
static STACK_OF(EVP_PKEY_ASN1_METHOD) *app_methods = NULL;
|
||||
|
||||
|
||||
|
||||
#ifdef TEST
|
||||
void main()
|
||||
{
|
||||
int i;
|
||||
for (i = 0;
|
||||
i < sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
|
||||
i++)
|
||||
fprintf(stderr, "Number %d id=%d (%s)\n", i,
|
||||
standard_methods[i]->pkey_id,
|
||||
OBJ_nid2sn(standard_methods[i]->pkey_id));
|
||||
}
|
||||
{
|
||||
int i;
|
||||
for (i = 0;
|
||||
i < sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *); i++)
|
||||
fprintf(stderr, "Number %d id=%d (%s)\n", i,
|
||||
standard_methods[i]->pkey_id,
|
||||
OBJ_nid2sn(standard_methods[i]->pkey_id));
|
||||
}
|
||||
#endif
|
||||
|
||||
DECLARE_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
|
||||
const EVP_PKEY_ASN1_METHOD *, ameth);
|
||||
const EVP_PKEY_ASN1_METHOD *, ameth);
|
||||
|
||||
static int ameth_cmp(const EVP_PKEY_ASN1_METHOD * const *a,
|
||||
const EVP_PKEY_ASN1_METHOD * const *b)
|
||||
{
|
||||
return ((*a)->pkey_id - (*b)->pkey_id);
|
||||
}
|
||||
static int ameth_cmp(const EVP_PKEY_ASN1_METHOD *const *a,
|
||||
const EVP_PKEY_ASN1_METHOD *const *b)
|
||||
{
|
||||
return ((*a)->pkey_id - (*b)->pkey_id);
|
||||
}
|
||||
|
||||
IMPLEMENT_OBJ_BSEARCH_CMP_FN(const EVP_PKEY_ASN1_METHOD *,
|
||||
const EVP_PKEY_ASN1_METHOD *, ameth);
|
||||
const EVP_PKEY_ASN1_METHOD *, ameth);
|
||||
|
||||
int EVP_PKEY_asn1_get_count(void)
|
||||
{
|
||||
int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
|
||||
if (app_methods)
|
||||
num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
|
||||
return num;
|
||||
}
|
||||
{
|
||||
int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *);
|
||||
if (app_methods)
|
||||
num += sk_EVP_PKEY_ASN1_METHOD_num(app_methods);
|
||||
return num;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_get0(int idx)
|
||||
{
|
||||
int num = sizeof(standard_methods)/sizeof(EVP_PKEY_ASN1_METHOD *);
|
||||
if (idx < 0)
|
||||
return NULL;
|
||||
if (idx < num)
|
||||
return standard_methods[idx];
|
||||
idx -= num;
|
||||
return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
|
||||
}
|
||||
{
|
||||
int num = sizeof(standard_methods) / sizeof(EVP_PKEY_ASN1_METHOD *);
|
||||
if (idx < 0)
|
||||
return NULL;
|
||||
if (idx < num)
|
||||
return standard_methods[idx];
|
||||
idx -= num;
|
||||
return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
|
||||
}
|
||||
|
||||
static const EVP_PKEY_ASN1_METHOD *pkey_asn1_find(int type)
|
||||
{
|
||||
EVP_PKEY_ASN1_METHOD tmp;
|
||||
const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
|
||||
tmp.pkey_id = type;
|
||||
if (app_methods)
|
||||
{
|
||||
int idx;
|
||||
idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
|
||||
if (idx >= 0)
|
||||
return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
|
||||
}
|
||||
ret = OBJ_bsearch_ameth(&t, standard_methods,
|
||||
sizeof(standard_methods)
|
||||
/sizeof(EVP_PKEY_ASN1_METHOD *));
|
||||
if (!ret || !*ret)
|
||||
return NULL;
|
||||
return *ret;
|
||||
}
|
||||
{
|
||||
EVP_PKEY_ASN1_METHOD tmp;
|
||||
const EVP_PKEY_ASN1_METHOD *t = &tmp, **ret;
|
||||
tmp.pkey_id = type;
|
||||
if (app_methods) {
|
||||
int idx;
|
||||
idx = sk_EVP_PKEY_ASN1_METHOD_find(app_methods, &tmp);
|
||||
if (idx >= 0)
|
||||
return sk_EVP_PKEY_ASN1_METHOD_value(app_methods, idx);
|
||||
}
|
||||
ret = OBJ_bsearch_ameth(&t, standard_methods, sizeof(standard_methods)
|
||||
/ sizeof(EVP_PKEY_ASN1_METHOD *));
|
||||
if (!ret || !*ret)
|
||||
return NULL;
|
||||
return *ret;
|
||||
}
|
||||
|
||||
/* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL
|
||||
* also search through engines and set *pe to a functional reference
|
||||
* to the engine implementing 'type' or NULL if no engine implements
|
||||
* it.
|
||||
/*
|
||||
* Find an implementation of an ASN1 algorithm. If 'pe' is not NULL also
|
||||
* search through engines and set *pe to a functional reference to the engine
|
||||
* implementing 'type' or NULL if no engine implements it.
|
||||
*/
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find(ENGINE **pe, int type)
|
||||
{
|
||||
const EVP_PKEY_ASN1_METHOD *t;
|
||||
{
|
||||
const EVP_PKEY_ASN1_METHOD *t;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
t = pkey_asn1_find(type);
|
||||
if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
|
||||
break;
|
||||
type = t->pkey_base_id;
|
||||
}
|
||||
if (pe)
|
||||
{
|
||||
for (;;) {
|
||||
t = pkey_asn1_find(type);
|
||||
if (!t || !(t->pkey_flags & ASN1_PKEY_ALIAS))
|
||||
break;
|
||||
type = t->pkey_base_id;
|
||||
}
|
||||
if (pe) {
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE *e;
|
||||
/* type will contain the final unaliased type */
|
||||
e = ENGINE_get_pkey_asn1_meth_engine(type);
|
||||
if (e)
|
||||
{
|
||||
*pe = e;
|
||||
return ENGINE_get_pkey_asn1_meth(e, type);
|
||||
}
|
||||
ENGINE *e;
|
||||
/* type will contain the final unaliased type */
|
||||
e = ENGINE_get_pkey_asn1_meth_engine(type);
|
||||
if (e) {
|
||||
*pe = e;
|
||||
return ENGINE_get_pkey_asn1_meth(e, type);
|
||||
}
|
||||
#endif
|
||||
*pe = NULL;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
*pe = NULL;
|
||||
}
|
||||
return t;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_find_str(ENGINE **pe,
|
||||
const char *str, int len)
|
||||
{
|
||||
int i;
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
if (len == -1)
|
||||
len = strlen(str);
|
||||
if (pe)
|
||||
{
|
||||
const char *str, int len)
|
||||
{
|
||||
int i;
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
if (len == -1)
|
||||
len = strlen(str);
|
||||
if (pe) {
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
ENGINE *e;
|
||||
ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
|
||||
if (ameth)
|
||||
{
|
||||
/* Convert structural into
|
||||
* functional reference
|
||||
*/
|
||||
if (!ENGINE_init(e))
|
||||
ameth = NULL;
|
||||
ENGINE_free(e);
|
||||
*pe = e;
|
||||
return ameth;
|
||||
}
|
||||
ENGINE *e;
|
||||
ameth = ENGINE_pkey_asn1_find_str(&e, str, len);
|
||||
if (ameth) {
|
||||
/*
|
||||
* Convert structural into functional reference
|
||||
*/
|
||||
if (!ENGINE_init(e))
|
||||
ameth = NULL;
|
||||
ENGINE_free(e);
|
||||
*pe = e;
|
||||
return ameth;
|
||||
}
|
||||
#endif
|
||||
*pe = NULL;
|
||||
}
|
||||
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++)
|
||||
{
|
||||
ameth = EVP_PKEY_asn1_get0(i);
|
||||
if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
|
||||
continue;
|
||||
if (((int)strlen(ameth->pem_str) == len) &&
|
||||
!strncasecmp(ameth->pem_str, str, len))
|
||||
return ameth;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
*pe = NULL;
|
||||
}
|
||||
for (i = 0; i < EVP_PKEY_asn1_get_count(); i++) {
|
||||
ameth = EVP_PKEY_asn1_get0(i);
|
||||
if (ameth->pkey_flags & ASN1_PKEY_ALIAS)
|
||||
continue;
|
||||
if (((int)strlen(ameth->pem_str) == len) &&
|
||||
!strncasecmp(ameth->pem_str, str, len))
|
||||
return ameth;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int EVP_PKEY_asn1_add0(const EVP_PKEY_ASN1_METHOD *ameth)
|
||||
{
|
||||
if (app_methods == NULL)
|
||||
{
|
||||
app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
|
||||
if (!app_methods)
|
||||
return 0;
|
||||
}
|
||||
if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
|
||||
return 0;
|
||||
sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
if (app_methods == NULL) {
|
||||
app_methods = sk_EVP_PKEY_ASN1_METHOD_new(ameth_cmp);
|
||||
if (!app_methods)
|
||||
return 0;
|
||||
}
|
||||
if (!sk_EVP_PKEY_ASN1_METHOD_push(app_methods, ameth))
|
||||
return 0;
|
||||
sk_EVP_PKEY_ASN1_METHOD_sort(app_methods);
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_asn1_add_alias(int to, int from)
|
||||
{
|
||||
EVP_PKEY_ASN1_METHOD *ameth;
|
||||
ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
|
||||
if (!ameth)
|
||||
return 0;
|
||||
ameth->pkey_base_id = to;
|
||||
return EVP_PKEY_asn1_add0(ameth);
|
||||
}
|
||||
{
|
||||
EVP_PKEY_ASN1_METHOD *ameth;
|
||||
ameth = EVP_PKEY_asn1_new(from, ASN1_PKEY_ALIAS, NULL, NULL);
|
||||
if (!ameth)
|
||||
return 0;
|
||||
ameth->pkey_base_id = to;
|
||||
if (!EVP_PKEY_asn1_add0(ameth)) {
|
||||
EVP_PKEY_asn1_free(ameth);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id, int *ppkey_flags,
|
||||
const char **pinfo, const char **ppem_str,
|
||||
const EVP_PKEY_ASN1_METHOD *ameth)
|
||||
{
|
||||
if (!ameth)
|
||||
return 0;
|
||||
if (ppkey_id)
|
||||
*ppkey_id = ameth->pkey_id;
|
||||
if (ppkey_base_id)
|
||||
*ppkey_base_id = ameth->pkey_base_id;
|
||||
if (ppkey_flags)
|
||||
*ppkey_flags = ameth->pkey_flags;
|
||||
if (pinfo)
|
||||
*pinfo = ameth->info;
|
||||
if (ppem_str)
|
||||
*ppem_str = ameth->pem_str;
|
||||
return 1;
|
||||
}
|
||||
int EVP_PKEY_asn1_get0_info(int *ppkey_id, int *ppkey_base_id,
|
||||
int *ppkey_flags, const char **pinfo,
|
||||
const char **ppem_str,
|
||||
const EVP_PKEY_ASN1_METHOD *ameth)
|
||||
{
|
||||
if (!ameth)
|
||||
return 0;
|
||||
if (ppkey_id)
|
||||
*ppkey_id = ameth->pkey_id;
|
||||
if (ppkey_base_id)
|
||||
*ppkey_base_id = ameth->pkey_base_id;
|
||||
if (ppkey_flags)
|
||||
*ppkey_flags = ameth->pkey_flags;
|
||||
if (pinfo)
|
||||
*pinfo = ameth->info;
|
||||
if (ppem_str)
|
||||
*ppem_str = ameth->pem_str;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const EVP_PKEY_ASN1_METHOD* EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
|
||||
{
|
||||
return pkey->ameth;
|
||||
}
|
||||
const EVP_PKEY_ASN1_METHOD *EVP_PKEY_get0_asn1(EVP_PKEY *pkey)
|
||||
{
|
||||
return pkey->ameth;
|
||||
}
|
||||
|
||||
EVP_PKEY_ASN1_METHOD* EVP_PKEY_asn1_new(int id, int flags,
|
||||
const char *pem_str, const char *info)
|
||||
{
|
||||
EVP_PKEY_ASN1_METHOD *ameth;
|
||||
ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
|
||||
if (!ameth)
|
||||
return NULL;
|
||||
EVP_PKEY_ASN1_METHOD *EVP_PKEY_asn1_new(int id, int flags,
|
||||
const char *pem_str, const char *info)
|
||||
{
|
||||
EVP_PKEY_ASN1_METHOD *ameth;
|
||||
ameth = OPENSSL_malloc(sizeof(EVP_PKEY_ASN1_METHOD));
|
||||
if (!ameth)
|
||||
return NULL;
|
||||
|
||||
memset(ameth, 0, sizeof(EVP_PKEY_ASN1_METHOD));
|
||||
memset(ameth, 0, sizeof(EVP_PKEY_ASN1_METHOD));
|
||||
|
||||
ameth->pkey_id = id;
|
||||
ameth->pkey_base_id = id;
|
||||
ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
|
||||
ameth->pkey_id = id;
|
||||
ameth->pkey_base_id = id;
|
||||
ameth->pkey_flags = flags | ASN1_PKEY_DYNAMIC;
|
||||
|
||||
if (info)
|
||||
{
|
||||
ameth->info = BUF_strdup(info);
|
||||
if (!ameth->info)
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
ameth->info = NULL;
|
||||
if (info) {
|
||||
ameth->info = BUF_strdup(info);
|
||||
if (!ameth->info)
|
||||
goto err;
|
||||
} else
|
||||
ameth->info = NULL;
|
||||
|
||||
if (pem_str)
|
||||
{
|
||||
ameth->pem_str = BUF_strdup(pem_str);
|
||||
if (!ameth->pem_str)
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
ameth->pem_str = NULL;
|
||||
if (pem_str) {
|
||||
ameth->pem_str = BUF_strdup(pem_str);
|
||||
if (!ameth->pem_str)
|
||||
goto err;
|
||||
} else
|
||||
ameth->pem_str = NULL;
|
||||
|
||||
ameth->pub_decode = 0;
|
||||
ameth->pub_encode = 0;
|
||||
ameth->pub_cmp = 0;
|
||||
ameth->pub_print = 0;
|
||||
ameth->pub_decode = 0;
|
||||
ameth->pub_encode = 0;
|
||||
ameth->pub_cmp = 0;
|
||||
ameth->pub_print = 0;
|
||||
|
||||
ameth->priv_decode = 0;
|
||||
ameth->priv_encode = 0;
|
||||
ameth->priv_print = 0;
|
||||
ameth->priv_decode = 0;
|
||||
ameth->priv_encode = 0;
|
||||
ameth->priv_print = 0;
|
||||
|
||||
ameth->old_priv_encode = 0;
|
||||
ameth->old_priv_decode = 0;
|
||||
ameth->old_priv_encode = 0;
|
||||
ameth->old_priv_decode = 0;
|
||||
|
||||
ameth->item_verify = 0;
|
||||
ameth->item_sign = 0;
|
||||
ameth->item_verify = 0;
|
||||
ameth->item_sign = 0;
|
||||
|
||||
ameth->pkey_size = 0;
|
||||
ameth->pkey_bits = 0;
|
||||
ameth->pkey_size = 0;
|
||||
ameth->pkey_bits = 0;
|
||||
|
||||
ameth->param_decode = 0;
|
||||
ameth->param_encode = 0;
|
||||
ameth->param_missing = 0;
|
||||
ameth->param_copy = 0;
|
||||
ameth->param_cmp = 0;
|
||||
ameth->param_print = 0;
|
||||
ameth->param_decode = 0;
|
||||
ameth->param_encode = 0;
|
||||
ameth->param_missing = 0;
|
||||
ameth->param_copy = 0;
|
||||
ameth->param_cmp = 0;
|
||||
ameth->param_print = 0;
|
||||
|
||||
ameth->pkey_free = 0;
|
||||
ameth->pkey_ctrl = 0;
|
||||
ameth->pkey_free = 0;
|
||||
ameth->pkey_ctrl = 0;
|
||||
|
||||
return ameth;
|
||||
return ameth;
|
||||
|
||||
err:
|
||||
err:
|
||||
|
||||
EVP_PKEY_asn1_free(ameth);
|
||||
return NULL;
|
||||
EVP_PKEY_asn1_free(ameth);
|
||||
return NULL;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
|
||||
const EVP_PKEY_ASN1_METHOD *src)
|
||||
{
|
||||
void EVP_PKEY_asn1_copy(EVP_PKEY_ASN1_METHOD *dst,
|
||||
const EVP_PKEY_ASN1_METHOD *src)
|
||||
{
|
||||
|
||||
dst->pub_decode = src->pub_decode;
|
||||
dst->pub_encode = src->pub_encode;
|
||||
dst->pub_cmp = src->pub_cmp;
|
||||
dst->pub_print = src->pub_print;
|
||||
dst->pub_decode = src->pub_decode;
|
||||
dst->pub_encode = src->pub_encode;
|
||||
dst->pub_cmp = src->pub_cmp;
|
||||
dst->pub_print = src->pub_print;
|
||||
|
||||
dst->priv_decode = src->priv_decode;
|
||||
dst->priv_encode = src->priv_encode;
|
||||
dst->priv_print = src->priv_print;
|
||||
dst->priv_decode = src->priv_decode;
|
||||
dst->priv_encode = src->priv_encode;
|
||||
dst->priv_print = src->priv_print;
|
||||
|
||||
dst->old_priv_encode = src->old_priv_encode;
|
||||
dst->old_priv_decode = src->old_priv_decode;
|
||||
dst->old_priv_encode = src->old_priv_encode;
|
||||
dst->old_priv_decode = src->old_priv_decode;
|
||||
|
||||
dst->pkey_size = src->pkey_size;
|
||||
dst->pkey_bits = src->pkey_bits;
|
||||
dst->pkey_size = src->pkey_size;
|
||||
dst->pkey_bits = src->pkey_bits;
|
||||
|
||||
dst->param_decode = src->param_decode;
|
||||
dst->param_encode = src->param_encode;
|
||||
dst->param_missing = src->param_missing;
|
||||
dst->param_copy = src->param_copy;
|
||||
dst->param_cmp = src->param_cmp;
|
||||
dst->param_print = src->param_print;
|
||||
dst->param_decode = src->param_decode;
|
||||
dst->param_encode = src->param_encode;
|
||||
dst->param_missing = src->param_missing;
|
||||
dst->param_copy = src->param_copy;
|
||||
dst->param_cmp = src->param_cmp;
|
||||
dst->param_print = src->param_print;
|
||||
|
||||
dst->pkey_free = src->pkey_free;
|
||||
dst->pkey_ctrl = src->pkey_ctrl;
|
||||
dst->pkey_free = src->pkey_free;
|
||||
dst->pkey_ctrl = src->pkey_ctrl;
|
||||
|
||||
dst->item_sign = src->item_sign;
|
||||
dst->item_verify = src->item_verify;
|
||||
dst->item_sign = src->item_sign;
|
||||
dst->item_verify = src->item_verify;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_free(EVP_PKEY_ASN1_METHOD *ameth)
|
||||
{
|
||||
if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC))
|
||||
{
|
||||
if (ameth->pem_str)
|
||||
OPENSSL_free(ameth->pem_str);
|
||||
if (ameth->info)
|
||||
OPENSSL_free(ameth->info);
|
||||
OPENSSL_free(ameth);
|
||||
}
|
||||
}
|
||||
{
|
||||
if (ameth && (ameth->pkey_flags & ASN1_PKEY_DYNAMIC)) {
|
||||
if (ameth->pem_str)
|
||||
OPENSSL_free(ameth->pem_str);
|
||||
if (ameth->info)
|
||||
OPENSSL_free(ameth->info);
|
||||
OPENSSL_free(ameth);
|
||||
}
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_set_public(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub),
|
||||
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk),
|
||||
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
|
||||
int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx),
|
||||
int (*pkey_size)(const EVP_PKEY *pk),
|
||||
int (*pkey_bits)(const EVP_PKEY *pk))
|
||||
{
|
||||
ameth->pub_decode = pub_decode;
|
||||
ameth->pub_encode = pub_encode;
|
||||
ameth->pub_cmp = pub_cmp;
|
||||
ameth->pub_print = pub_print;
|
||||
ameth->pkey_size = pkey_size;
|
||||
ameth->pkey_bits = pkey_bits;
|
||||
}
|
||||
int (*pub_decode) (EVP_PKEY *pk,
|
||||
X509_PUBKEY *pub),
|
||||
int (*pub_encode) (X509_PUBKEY *pub,
|
||||
const EVP_PKEY *pk),
|
||||
int (*pub_cmp) (const EVP_PKEY *a,
|
||||
const EVP_PKEY *b),
|
||||
int (*pub_print) (BIO *out,
|
||||
const EVP_PKEY *pkey,
|
||||
int indent, ASN1_PCTX *pctx),
|
||||
int (*pkey_size) (const EVP_PKEY *pk),
|
||||
int (*pkey_bits) (const EVP_PKEY *pk))
|
||||
{
|
||||
ameth->pub_decode = pub_decode;
|
||||
ameth->pub_encode = pub_encode;
|
||||
ameth->pub_cmp = pub_cmp;
|
||||
ameth->pub_print = pub_print;
|
||||
ameth->pkey_size = pkey_size;
|
||||
ameth->pkey_bits = pkey_bits;
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_set_private(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf),
|
||||
int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk),
|
||||
int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx))
|
||||
{
|
||||
ameth->priv_decode = priv_decode;
|
||||
ameth->priv_encode = priv_encode;
|
||||
ameth->priv_print = priv_print;
|
||||
}
|
||||
int (*priv_decode) (EVP_PKEY *pk,
|
||||
PKCS8_PRIV_KEY_INFO
|
||||
*p8inf),
|
||||
int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8,
|
||||
const EVP_PKEY *pk),
|
||||
int (*priv_print) (BIO *out,
|
||||
const EVP_PKEY *pkey,
|
||||
int indent,
|
||||
ASN1_PCTX *pctx))
|
||||
{
|
||||
ameth->priv_decode = priv_decode;
|
||||
ameth->priv_encode = priv_encode;
|
||||
ameth->priv_print = priv_print;
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_set_param(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
int (*param_decode)(EVP_PKEY *pkey,
|
||||
const unsigned char **pder, int derlen),
|
||||
int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder),
|
||||
int (*param_missing)(const EVP_PKEY *pk),
|
||||
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from),
|
||||
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b),
|
||||
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx))
|
||||
{
|
||||
ameth->param_decode = param_decode;
|
||||
ameth->param_encode = param_encode;
|
||||
ameth->param_missing = param_missing;
|
||||
ameth->param_copy = param_copy;
|
||||
ameth->param_cmp = param_cmp;
|
||||
ameth->param_print = param_print;
|
||||
}
|
||||
int (*param_decode) (EVP_PKEY *pkey,
|
||||
const unsigned char **pder,
|
||||
int derlen),
|
||||
int (*param_encode) (const EVP_PKEY *pkey,
|
||||
unsigned char **pder),
|
||||
int (*param_missing) (const EVP_PKEY *pk),
|
||||
int (*param_copy) (EVP_PKEY *to,
|
||||
const EVP_PKEY *from),
|
||||
int (*param_cmp) (const EVP_PKEY *a,
|
||||
const EVP_PKEY *b),
|
||||
int (*param_print) (BIO *out,
|
||||
const EVP_PKEY *pkey,
|
||||
int indent, ASN1_PCTX *pctx))
|
||||
{
|
||||
ameth->param_decode = param_decode;
|
||||
ameth->param_encode = param_encode;
|
||||
ameth->param_missing = param_missing;
|
||||
ameth->param_copy = param_copy;
|
||||
ameth->param_cmp = param_cmp;
|
||||
ameth->param_print = param_print;
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_set_free(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
void (*pkey_free)(EVP_PKEY *pkey))
|
||||
{
|
||||
ameth->pkey_free = pkey_free;
|
||||
}
|
||||
void (*pkey_free) (EVP_PKEY *pkey))
|
||||
{
|
||||
ameth->pkey_free = pkey_free;
|
||||
}
|
||||
|
||||
void EVP_PKEY_asn1_set_ctrl(EVP_PKEY_ASN1_METHOD *ameth,
|
||||
int (*pkey_ctrl)(EVP_PKEY *pkey, int op,
|
||||
long arg1, void *arg2))
|
||||
{
|
||||
ameth->pkey_ctrl = pkey_ctrl;
|
||||
}
|
||||
int (*pkey_ctrl) (EVP_PKEY *pkey, int op,
|
||||
long arg1, void *arg2))
|
||||
{
|
||||
ameth->pkey_ctrl = pkey_ctrl;
|
||||
}
|
||||
|
||||
@ -1,13 +1,13 @@
|
||||
/* crypto/asn1/asn1_err.c */
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2011 The OpenSSL Project. All rights reserved.
|
||||
* Copyright (c) 1999-2014 The OpenSSL Project. All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -53,7 +53,8 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* NOTE: this file was auto generated by the mkerr.pl script: any changes
|
||||
/*
|
||||
* NOTE: this file was auto generated by the mkerr.pl script: any changes
|
||||
* made to it will be overwritten when the script next updates this file,
|
||||
* only reason strings will be preserved.
|
||||
*/
|
||||
@ -65,268 +66,289 @@
|
||||
/* BEGIN ERROR CODES */
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
#define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0)
|
||||
#define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason)
|
||||
# define ERR_FUNC(func) ERR_PACK(ERR_LIB_ASN1,func,0)
|
||||
# define ERR_REASON(reason) ERR_PACK(ERR_LIB_ASN1,0,reason)
|
||||
|
||||
static ERR_STRING_DATA ASN1_str_functs[]=
|
||||
{
|
||||
{ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT), "a2d_ASN1_OBJECT"},
|
||||
{ERR_FUNC(ASN1_F_A2I_ASN1_ENUMERATED), "a2i_ASN1_ENUMERATED"},
|
||||
{ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER), "a2i_ASN1_INTEGER"},
|
||||
{ERR_FUNC(ASN1_F_A2I_ASN1_STRING), "a2i_ASN1_STRING"},
|
||||
{ERR_FUNC(ASN1_F_APPEND_EXP), "APPEND_EXP"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT), "ASN1_BIT_STRING_set_bit"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_CB), "ASN1_CB"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN), "ASN1_CHECK_TLEN"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_COLLATE_PRIMITIVE), "ASN1_COLLATE_PRIMITIVE"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_COLLECT), "ASN1_COLLECT"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE), "ASN1_D2I_EX_PRIMITIVE"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_D2I_FP), "ASN1_d2i_fp"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO), "ASN1_D2I_READ_BIO"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_DIGEST), "ASN1_digest"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_DO_ADB), "ASN1_DO_ADB"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_DUP), "ASN1_dup"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_SET), "ASN1_ENUMERATED_set"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_EX_C2I), "ASN1_EX_C2I"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ), "ASN1_GENERALIZEDTIME_adj"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_NEW"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_INTEGER_SET), "ASN1_INTEGER_set"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_INTEGER_TO_BN), "ASN1_INTEGER_to_BN"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP), "ASN1_item_d2i_fp"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW), "ASN1_ITEM_EX_COMBINE_NEW"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I), "ASN1_ITEM_EX_D2I"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_new"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_SIGN), "ASN1_sign"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_STR2TYPE), "ASN1_STR2TYPE"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_STRING_SET), "ASN1_STRING_set"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD), "ASN1_STRING_TABLE_add"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW), "ASN1_STRING_type_new"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "ASN1_TEMPLATE_EX_D2I"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "ASN1_TEMPLATE_NEW"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "ASN1_TEMPLATE_NOEXP_D2I"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TIME_ADJ), "ASN1_TIME_adj"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TIME_SET), "ASN1_TIME_set"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING), "ASN1_TYPE_get_int_octetstring"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ), "ASN1_UTCTIME_adj"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"},
|
||||
{ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"},
|
||||
{ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"},
|
||||
{ERR_FUNC(ASN1_F_BIO_NEW_NDEF), "BIO_new_NDEF"},
|
||||
{ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"},
|
||||
{ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"},
|
||||
{ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"},
|
||||
{ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING), "c2i_ASN1_BIT_STRING"},
|
||||
{ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER), "c2i_ASN1_INTEGER"},
|
||||
{ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT), "c2i_ASN1_OBJECT"},
|
||||
{ERR_FUNC(ASN1_F_COLLECT_DATA), "COLLECT_DATA"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_BIT_STRING), "D2I_ASN1_BIT_STRING"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN), "d2i_ASN1_BOOLEAN"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_BYTES), "d2i_ASN1_bytes"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME), "D2I_ASN1_GENERALIZEDTIME"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "D2I_ASN1_HEADER"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER), "D2I_ASN1_INTEGER"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_SET), "d2i_ASN1_SET"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES), "d2i_ASN1_type_bytes"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME), "D2I_ASN1_UTCTIME"},
|
||||
{ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"},
|
||||
{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA), "d2i_Netscape_RSA"},
|
||||
{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2), "D2I_NETSCAPE_RSA_2"},
|
||||
{ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"},
|
||||
{ERR_FUNC(ASN1_F_D2I_PUBLICKEY), "d2i_PublicKey"},
|
||||
{ERR_FUNC(ASN1_F_D2I_RSA_NET), "d2i_RSA_NET"},
|
||||
{ERR_FUNC(ASN1_F_D2I_RSA_NET_2), "D2I_RSA_NET_2"},
|
||||
{ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"},
|
||||
{ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"},
|
||||
{ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"},
|
||||
{ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"},
|
||||
{ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"},
|
||||
{ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"},
|
||||
{ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"},
|
||||
{ERR_FUNC(ASN1_F_I2D_EC_PUBKEY), "i2d_EC_PUBKEY"},
|
||||
{ERR_FUNC(ASN1_F_I2D_PRIVATEKEY), "i2d_PrivateKey"},
|
||||
{ERR_FUNC(ASN1_F_I2D_PUBLICKEY), "i2d_PublicKey"},
|
||||
{ERR_FUNC(ASN1_F_I2D_RSA_NET), "i2d_RSA_NET"},
|
||||
{ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY), "i2d_RSA_PUBKEY"},
|
||||
{ERR_FUNC(ASN1_F_LONG_C2I), "LONG_C2I"},
|
||||
{ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"},
|
||||
{ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"},
|
||||
{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"},
|
||||
{ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"},
|
||||
{ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"},
|
||||
{ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"},
|
||||
{ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"},
|
||||
{ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"},
|
||||
{ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"},
|
||||
{ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"},
|
||||
{ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"},
|
||||
{ERR_FUNC(ASN1_F_X509_NAME_ENCODE), "X509_NAME_ENCODE"},
|
||||
{ERR_FUNC(ASN1_F_X509_NAME_EX_D2I), "X509_NAME_EX_D2I"},
|
||||
{ERR_FUNC(ASN1_F_X509_NAME_EX_NEW), "X509_NAME_EX_NEW"},
|
||||
{ERR_FUNC(ASN1_F_X509_NEW), "X509_NEW"},
|
||||
{ERR_FUNC(ASN1_F_X509_PKEY_NEW), "X509_PKEY_new"},
|
||||
{0,NULL}
|
||||
};
|
||||
static ERR_STRING_DATA ASN1_str_functs[] = {
|
||||
{ERR_FUNC(ASN1_F_A2D_ASN1_OBJECT), "a2d_ASN1_OBJECT"},
|
||||
{ERR_FUNC(ASN1_F_A2I_ASN1_ENUMERATED), "a2i_ASN1_ENUMERATED"},
|
||||
{ERR_FUNC(ASN1_F_A2I_ASN1_INTEGER), "a2i_ASN1_INTEGER"},
|
||||
{ERR_FUNC(ASN1_F_A2I_ASN1_STRING), "a2i_ASN1_STRING"},
|
||||
{ERR_FUNC(ASN1_F_APPEND_EXP), "APPEND_EXP"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_BIT_STRING_SET_BIT), "ASN1_BIT_STRING_set_bit"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_CB), "ASN1_CB"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_CHECK_TLEN), "ASN1_CHECK_TLEN"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_COLLATE_PRIMITIVE), "ASN1_COLLATE_PRIMITIVE"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_COLLECT), "ASN1_COLLECT"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_D2I_EX_PRIMITIVE), "ASN1_D2I_EX_PRIMITIVE"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_D2I_FP), "ASN1_d2i_fp"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_D2I_READ_BIO), "ASN1_D2I_READ_BIO"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_DIGEST), "ASN1_digest"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_DO_ADB), "ASN1_DO_ADB"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_DUP), "ASN1_dup"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_SET), "ASN1_ENUMERATED_set"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ENUMERATED_TO_BN), "ASN1_ENUMERATED_to_BN"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_EX_C2I), "ASN1_EX_C2I"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_FIND_END), "ASN1_FIND_END"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_ADJ), "ASN1_GENERALIZEDTIME_adj"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_GENERALIZEDTIME_SET), "ASN1_GENERALIZEDTIME_set"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_GENERATE_V3), "ASN1_generate_v3"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_GET_OBJECT), "ASN1_get_object"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_HEADER_NEW), "ASN1_HEADER_NEW"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_I2D_BIO), "ASN1_i2d_bio"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_I2D_FP), "ASN1_i2d_fp"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_INTEGER_SET), "ASN1_INTEGER_set"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_INTEGER_TO_BN), "ASN1_INTEGER_to_BN"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_D2I_FP), "ASN1_item_d2i_fp"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_DUP), "ASN1_item_dup"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW), "ASN1_ITEM_EX_COMBINE_NEW"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_EX_D2I), "ASN1_ITEM_EX_D2I"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_BIO), "ASN1_item_i2d_bio"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_I2D_FP), "ASN1_item_i2d_fp"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_PACK), "ASN1_item_pack"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN), "ASN1_item_sign"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_SIGN_CTX), "ASN1_item_sign_ctx"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_UNPACK), "ASN1_item_unpack"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_ITEM_VERIFY), "ASN1_item_verify"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_MBSTRING_NCOPY), "ASN1_mbstring_ncopy"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_OBJECT_NEW), "ASN1_OBJECT_new"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_OUTPUT_DATA), "ASN1_OUTPUT_DATA"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_PACK_STRING), "ASN1_pack_string"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_PCTX_NEW), "ASN1_PCTX_new"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_PKCS5_PBE_SET), "ASN1_PKCS5_PBE_SET"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_SEQ_PACK), "ASN1_seq_pack"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_SEQ_UNPACK), "ASN1_seq_unpack"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_SIGN), "ASN1_sign"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_STR2TYPE), "ASN1_STR2TYPE"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_STRING_SET), "ASN1_STRING_set"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_STRING_TABLE_ADD), "ASN1_STRING_TABLE_add"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_STRING_TYPE_NEW), "ASN1_STRING_type_new"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_EX_D2I), "ASN1_TEMPLATE_EX_D2I"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NEW), "ASN1_TEMPLATE_NEW"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TEMPLATE_NOEXP_D2I), "ASN1_TEMPLATE_NOEXP_D2I"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TIME_ADJ), "ASN1_TIME_adj"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TIME_SET), "ASN1_TIME_set"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING),
|
||||
"ASN1_TYPE_get_int_octetstring"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_TYPE_GET_OCTETSTRING), "ASN1_TYPE_get_octetstring"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_UNPACK_STRING), "ASN1_unpack_string"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_UTCTIME_ADJ), "ASN1_UTCTIME_adj"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_UTCTIME_SET), "ASN1_UTCTIME_set"},
|
||||
{ERR_FUNC(ASN1_F_ASN1_VERIFY), "ASN1_verify"},
|
||||
{ERR_FUNC(ASN1_F_B64_READ_ASN1), "B64_READ_ASN1"},
|
||||
{ERR_FUNC(ASN1_F_B64_WRITE_ASN1), "B64_WRITE_ASN1"},
|
||||
{ERR_FUNC(ASN1_F_BIO_NEW_NDEF), "BIO_new_NDEF"},
|
||||
{ERR_FUNC(ASN1_F_BITSTR_CB), "BITSTR_CB"},
|
||||
{ERR_FUNC(ASN1_F_BN_TO_ASN1_ENUMERATED), "BN_to_ASN1_ENUMERATED"},
|
||||
{ERR_FUNC(ASN1_F_BN_TO_ASN1_INTEGER), "BN_to_ASN1_INTEGER"},
|
||||
{ERR_FUNC(ASN1_F_C2I_ASN1_BIT_STRING), "c2i_ASN1_BIT_STRING"},
|
||||
{ERR_FUNC(ASN1_F_C2I_ASN1_INTEGER), "c2i_ASN1_INTEGER"},
|
||||
{ERR_FUNC(ASN1_F_C2I_ASN1_OBJECT), "c2i_ASN1_OBJECT"},
|
||||
{ERR_FUNC(ASN1_F_COLLECT_DATA), "COLLECT_DATA"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_BIT_STRING), "D2I_ASN1_BIT_STRING"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_BOOLEAN), "d2i_ASN1_BOOLEAN"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_BYTES), "d2i_ASN1_bytes"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_GENERALIZEDTIME), "D2I_ASN1_GENERALIZEDTIME"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_HEADER), "D2I_ASN1_HEADER"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_INTEGER), "D2I_ASN1_INTEGER"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_OBJECT), "d2i_ASN1_OBJECT"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_SET), "d2i_ASN1_SET"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_TYPE_BYTES), "d2i_ASN1_type_bytes"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_UINTEGER), "d2i_ASN1_UINTEGER"},
|
||||
{ERR_FUNC(ASN1_F_D2I_ASN1_UTCTIME), "D2I_ASN1_UTCTIME"},
|
||||
{ERR_FUNC(ASN1_F_D2I_AUTOPRIVATEKEY), "d2i_AutoPrivateKey"},
|
||||
{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA), "d2i_Netscape_RSA"},
|
||||
{ERR_FUNC(ASN1_F_D2I_NETSCAPE_RSA_2), "D2I_NETSCAPE_RSA_2"},
|
||||
{ERR_FUNC(ASN1_F_D2I_PRIVATEKEY), "d2i_PrivateKey"},
|
||||
{ERR_FUNC(ASN1_F_D2I_PUBLICKEY), "d2i_PublicKey"},
|
||||
{ERR_FUNC(ASN1_F_D2I_RSA_NET), "d2i_RSA_NET"},
|
||||
{ERR_FUNC(ASN1_F_D2I_RSA_NET_2), "D2I_RSA_NET_2"},
|
||||
{ERR_FUNC(ASN1_F_D2I_X509), "D2I_X509"},
|
||||
{ERR_FUNC(ASN1_F_D2I_X509_CINF), "D2I_X509_CINF"},
|
||||
{ERR_FUNC(ASN1_F_D2I_X509_PKEY), "d2i_X509_PKEY"},
|
||||
{ERR_FUNC(ASN1_F_I2D_ASN1_BIO_STREAM), "i2d_ASN1_bio_stream"},
|
||||
{ERR_FUNC(ASN1_F_I2D_ASN1_SET), "i2d_ASN1_SET"},
|
||||
{ERR_FUNC(ASN1_F_I2D_ASN1_TIME), "I2D_ASN1_TIME"},
|
||||
{ERR_FUNC(ASN1_F_I2D_DSA_PUBKEY), "i2d_DSA_PUBKEY"},
|
||||
{ERR_FUNC(ASN1_F_I2D_EC_PUBKEY), "i2d_EC_PUBKEY"},
|
||||
{ERR_FUNC(ASN1_F_I2D_PRIVATEKEY), "i2d_PrivateKey"},
|
||||
{ERR_FUNC(ASN1_F_I2D_PUBLICKEY), "i2d_PublicKey"},
|
||||
{ERR_FUNC(ASN1_F_I2D_RSA_NET), "i2d_RSA_NET"},
|
||||
{ERR_FUNC(ASN1_F_I2D_RSA_PUBKEY), "i2d_RSA_PUBKEY"},
|
||||
{ERR_FUNC(ASN1_F_LONG_C2I), "LONG_C2I"},
|
||||
{ERR_FUNC(ASN1_F_OID_MODULE_INIT), "OID_MODULE_INIT"},
|
||||
{ERR_FUNC(ASN1_F_PARSE_TAGGING), "PARSE_TAGGING"},
|
||||
{ERR_FUNC(ASN1_F_PKCS5_PBE2_SET_IV), "PKCS5_pbe2_set_iv"},
|
||||
{ERR_FUNC(ASN1_F_PKCS5_PBE_SET), "PKCS5_pbe_set"},
|
||||
{ERR_FUNC(ASN1_F_PKCS5_PBE_SET0_ALGOR), "PKCS5_pbe_set0_algor"},
|
||||
{ERR_FUNC(ASN1_F_PKCS5_PBKDF2_SET), "PKCS5_pbkdf2_set"},
|
||||
{ERR_FUNC(ASN1_F_SMIME_READ_ASN1), "SMIME_read_ASN1"},
|
||||
{ERR_FUNC(ASN1_F_SMIME_TEXT), "SMIME_text"},
|
||||
{ERR_FUNC(ASN1_F_X509_CINF_NEW), "X509_CINF_NEW"},
|
||||
{ERR_FUNC(ASN1_F_X509_CRL_ADD0_REVOKED), "X509_CRL_add0_revoked"},
|
||||
{ERR_FUNC(ASN1_F_X509_INFO_NEW), "X509_INFO_new"},
|
||||
{ERR_FUNC(ASN1_F_X509_NAME_ENCODE), "X509_NAME_ENCODE"},
|
||||
{ERR_FUNC(ASN1_F_X509_NAME_EX_D2I), "X509_NAME_EX_D2I"},
|
||||
{ERR_FUNC(ASN1_F_X509_NAME_EX_NEW), "X509_NAME_EX_NEW"},
|
||||
{ERR_FUNC(ASN1_F_X509_NEW), "X509_NEW"},
|
||||
{ERR_FUNC(ASN1_F_X509_PKEY_NEW), "X509_PKEY_new"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
static ERR_STRING_DATA ASN1_str_reasons[]=
|
||||
{
|
||||
{ERR_REASON(ASN1_R_ADDING_OBJECT) ,"adding object"},
|
||||
{ERR_REASON(ASN1_R_ASN1_PARSE_ERROR) ,"asn1 parse error"},
|
||||
{ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR) ,"asn1 sig parse error"},
|
||||
{ERR_REASON(ASN1_R_AUX_ERROR) ,"aux error"},
|
||||
{ERR_REASON(ASN1_R_BAD_CLASS) ,"bad class"},
|
||||
{ERR_REASON(ASN1_R_BAD_OBJECT_HEADER) ,"bad object header"},
|
||||
{ERR_REASON(ASN1_R_BAD_PASSWORD_READ) ,"bad password read"},
|
||||
{ERR_REASON(ASN1_R_BAD_TAG) ,"bad tag"},
|
||||
{ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH),"bmpstring is wrong length"},
|
||||
{ERR_REASON(ASN1_R_BN_LIB) ,"bn lib"},
|
||||
{ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH),"boolean is wrong length"},
|
||||
{ERR_REASON(ASN1_R_BUFFER_TOO_SMALL) ,"buffer too small"},
|
||||
{ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),"cipher has no object identifier"},
|
||||
{ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED),"context not initialised"},
|
||||
{ERR_REASON(ASN1_R_DATA_IS_WRONG) ,"data is wrong"},
|
||||
{ERR_REASON(ASN1_R_DECODE_ERROR) ,"decode error"},
|
||||
{ERR_REASON(ASN1_R_DECODING_ERROR) ,"decoding error"},
|
||||
{ERR_REASON(ASN1_R_DEPTH_EXCEEDED) ,"depth exceeded"},
|
||||
{ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),"digest and key type not supported"},
|
||||
{ERR_REASON(ASN1_R_ENCODE_ERROR) ,"encode error"},
|
||||
{ERR_REASON(ASN1_R_ERROR_GETTING_TIME) ,"error getting time"},
|
||||
{ERR_REASON(ASN1_R_ERROR_LOADING_SECTION),"error loading section"},
|
||||
{ERR_REASON(ASN1_R_ERROR_PARSING_SET_ELEMENT),"error parsing set element"},
|
||||
{ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS),"error setting cipher params"},
|
||||
{ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER) ,"expecting an integer"},
|
||||
{ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT) ,"expecting an object"},
|
||||
{ERR_REASON(ASN1_R_EXPECTING_A_BOOLEAN) ,"expecting a boolean"},
|
||||
{ERR_REASON(ASN1_R_EXPECTING_A_TIME) ,"expecting a time"},
|
||||
{ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH),"explicit length mismatch"},
|
||||
{ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED),"explicit tag not constructed"},
|
||||
{ERR_REASON(ASN1_R_FIELD_MISSING) ,"field missing"},
|
||||
{ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE) ,"first num too large"},
|
||||
{ERR_REASON(ASN1_R_HEADER_TOO_LONG) ,"header too long"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT),"illegal bitstring format"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN) ,"illegal boolean"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS) ,"illegal characters"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_FORMAT) ,"illegal format"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_HEX) ,"illegal hex"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG) ,"illegal implicit tag"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_INTEGER) ,"illegal integer"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING),"illegal nested tagging"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_NULL) ,"illegal null"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE) ,"illegal null value"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_OBJECT) ,"illegal object"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY) ,"illegal optional any"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE),"illegal options on item template"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY) ,"illegal tagged any"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE) ,"illegal time value"},
|
||||
{ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT),"integer not ascii format"},
|
||||
{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),"integer too large for long"},
|
||||
{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH),"invalid bmpstring length"},
|
||||
{ERR_REASON(ASN1_R_INVALID_DIGIT) ,"invalid digit"},
|
||||
{ERR_REASON(ASN1_R_INVALID_MIME_TYPE) ,"invalid mime type"},
|
||||
{ERR_REASON(ASN1_R_INVALID_MODIFIER) ,"invalid modifier"},
|
||||
{ERR_REASON(ASN1_R_INVALID_NUMBER) ,"invalid number"},
|
||||
{ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING),"invalid object encoding"},
|
||||
{ERR_REASON(ASN1_R_INVALID_SEPARATOR) ,"invalid separator"},
|
||||
{ERR_REASON(ASN1_R_INVALID_TIME_FORMAT) ,"invalid time format"},
|
||||
{ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),"invalid universalstring length"},
|
||||
{ERR_REASON(ASN1_R_INVALID_UTF8STRING) ,"invalid utf8string"},
|
||||
{ERR_REASON(ASN1_R_IV_TOO_LARGE) ,"iv too large"},
|
||||
{ERR_REASON(ASN1_R_LENGTH_ERROR) ,"length error"},
|
||||
{ERR_REASON(ASN1_R_LIST_ERROR) ,"list error"},
|
||||
{ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE) ,"mime no content type"},
|
||||
{ERR_REASON(ASN1_R_MIME_PARSE_ERROR) ,"mime parse error"},
|
||||
{ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR) ,"mime sig parse error"},
|
||||
{ERR_REASON(ASN1_R_MISSING_EOC) ,"missing eoc"},
|
||||
{ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER),"missing second number"},
|
||||
{ERR_REASON(ASN1_R_MISSING_VALUE) ,"missing value"},
|
||||
{ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL),"mstring not universal"},
|
||||
{ERR_REASON(ASN1_R_MSTRING_WRONG_TAG) ,"mstring wrong tag"},
|
||||
{ERR_REASON(ASN1_R_NESTED_ASN1_STRING) ,"nested asn1 string"},
|
||||
{ERR_REASON(ASN1_R_NON_HEX_CHARACTERS) ,"non hex characters"},
|
||||
{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT) ,"not ascii format"},
|
||||
{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA) ,"not enough data"},
|
||||
{ERR_REASON(ASN1_R_NO_CONTENT_TYPE) ,"no content type"},
|
||||
{ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST) ,"no default digest"},
|
||||
{ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE),"no matching choice type"},
|
||||
{ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),"no multipart body failure"},
|
||||
{ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY),"no multipart boundary"},
|
||||
{ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE) ,"no sig content type"},
|
||||
{ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH) ,"null is wrong length"},
|
||||
{ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT),"object not ascii format"},
|
||||
{ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS) ,"odd number of chars"},
|
||||
{ERR_REASON(ASN1_R_PRIVATE_KEY_HEADER_MISSING),"private key header missing"},
|
||||
{ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE),"second number too large"},
|
||||
{ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH),"sequence length mismatch"},
|
||||
{ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED),"sequence not constructed"},
|
||||
{ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG),"sequence or set needs config"},
|
||||
{ERR_REASON(ASN1_R_SHORT_LINE) ,"short line"},
|
||||
{ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE),"sig invalid mime type"},
|
||||
{ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED),"streaming not supported"},
|
||||
{ERR_REASON(ASN1_R_STRING_TOO_LONG) ,"string too long"},
|
||||
{ERR_REASON(ASN1_R_STRING_TOO_SHORT) ,"string too short"},
|
||||
{ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH) ,"tag value too high"},
|
||||
{ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),"the asn1 object identifier is not known for this md"},
|
||||
{ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT),"time not ascii format"},
|
||||
{ERR_REASON(ASN1_R_TOO_LONG) ,"too long"},
|
||||
{ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED) ,"type not constructed"},
|
||||
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY),"unable to decode rsa key"},
|
||||
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),"unable to decode rsa private key"},
|
||||
{ERR_REASON(ASN1_R_UNEXPECTED_EOC) ,"unexpected eoc"},
|
||||
{ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH),"universalstring is wrong length"},
|
||||
{ERR_REASON(ASN1_R_UNKNOWN_FORMAT) ,"unknown format"},
|
||||
{ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),"unknown message digest algorithm"},
|
||||
{ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE) ,"unknown object type"},
|
||||
{ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE),"unknown public key type"},
|
||||
{ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),"unknown signature algorithm"},
|
||||
{ERR_REASON(ASN1_R_UNKNOWN_TAG) ,"unknown tag"},
|
||||
{ERR_REASON(ASN1_R_UNKOWN_FORMAT) ,"unknown format"},
|
||||
{ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),"unsupported any defined by type"},
|
||||
{ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER) ,"unsupported cipher"},
|
||||
{ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM),"unsupported encryption algorithm"},
|
||||
{ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),"unsupported public key type"},
|
||||
{ERR_REASON(ASN1_R_UNSUPPORTED_TYPE) ,"unsupported type"},
|
||||
{ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE),"wrong public key type"},
|
||||
{ERR_REASON(ASN1_R_WRONG_TAG) ,"wrong tag"},
|
||||
{ERR_REASON(ASN1_R_WRONG_TYPE) ,"wrong type"},
|
||||
{0,NULL}
|
||||
};
|
||||
static ERR_STRING_DATA ASN1_str_reasons[] = {
|
||||
{ERR_REASON(ASN1_R_ADDING_OBJECT), "adding object"},
|
||||
{ERR_REASON(ASN1_R_ASN1_PARSE_ERROR), "asn1 parse error"},
|
||||
{ERR_REASON(ASN1_R_ASN1_SIG_PARSE_ERROR), "asn1 sig parse error"},
|
||||
{ERR_REASON(ASN1_R_AUX_ERROR), "aux error"},
|
||||
{ERR_REASON(ASN1_R_BAD_CLASS), "bad class"},
|
||||
{ERR_REASON(ASN1_R_BAD_OBJECT_HEADER), "bad object header"},
|
||||
{ERR_REASON(ASN1_R_BAD_PASSWORD_READ), "bad password read"},
|
||||
{ERR_REASON(ASN1_R_BAD_TAG), "bad tag"},
|
||||
{ERR_REASON(ASN1_R_BMPSTRING_IS_WRONG_LENGTH),
|
||||
"bmpstring is wrong length"},
|
||||
{ERR_REASON(ASN1_R_BN_LIB), "bn lib"},
|
||||
{ERR_REASON(ASN1_R_BOOLEAN_IS_WRONG_LENGTH), "boolean is wrong length"},
|
||||
{ERR_REASON(ASN1_R_BUFFER_TOO_SMALL), "buffer too small"},
|
||||
{ERR_REASON(ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER),
|
||||
"cipher has no object identifier"},
|
||||
{ERR_REASON(ASN1_R_CONTEXT_NOT_INITIALISED), "context not initialised"},
|
||||
{ERR_REASON(ASN1_R_DATA_IS_WRONG), "data is wrong"},
|
||||
{ERR_REASON(ASN1_R_DECODE_ERROR), "decode error"},
|
||||
{ERR_REASON(ASN1_R_DECODING_ERROR), "decoding error"},
|
||||
{ERR_REASON(ASN1_R_DEPTH_EXCEEDED), "depth exceeded"},
|
||||
{ERR_REASON(ASN1_R_DIGEST_AND_KEY_TYPE_NOT_SUPPORTED),
|
||||
"digest and key type not supported"},
|
||||
{ERR_REASON(ASN1_R_ENCODE_ERROR), "encode error"},
|
||||
{ERR_REASON(ASN1_R_ERROR_GETTING_TIME), "error getting time"},
|
||||
{ERR_REASON(ASN1_R_ERROR_LOADING_SECTION), "error loading section"},
|
||||
{ERR_REASON(ASN1_R_ERROR_PARSING_SET_ELEMENT),
|
||||
"error parsing set element"},
|
||||
{ERR_REASON(ASN1_R_ERROR_SETTING_CIPHER_PARAMS),
|
||||
"error setting cipher params"},
|
||||
{ERR_REASON(ASN1_R_EXPECTING_AN_INTEGER), "expecting an integer"},
|
||||
{ERR_REASON(ASN1_R_EXPECTING_AN_OBJECT), "expecting an object"},
|
||||
{ERR_REASON(ASN1_R_EXPECTING_A_BOOLEAN), "expecting a boolean"},
|
||||
{ERR_REASON(ASN1_R_EXPECTING_A_TIME), "expecting a time"},
|
||||
{ERR_REASON(ASN1_R_EXPLICIT_LENGTH_MISMATCH), "explicit length mismatch"},
|
||||
{ERR_REASON(ASN1_R_EXPLICIT_TAG_NOT_CONSTRUCTED),
|
||||
"explicit tag not constructed"},
|
||||
{ERR_REASON(ASN1_R_FIELD_MISSING), "field missing"},
|
||||
{ERR_REASON(ASN1_R_FIRST_NUM_TOO_LARGE), "first num too large"},
|
||||
{ERR_REASON(ASN1_R_HEADER_TOO_LONG), "header too long"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_BITSTRING_FORMAT), "illegal bitstring format"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_BOOLEAN), "illegal boolean"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_CHARACTERS), "illegal characters"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_FORMAT), "illegal format"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_HEX), "illegal hex"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_IMPLICIT_TAG), "illegal implicit tag"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_INTEGER), "illegal integer"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_NESTED_TAGGING), "illegal nested tagging"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_NULL), "illegal null"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_NULL_VALUE), "illegal null value"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_OBJECT), "illegal object"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_OPTIONAL_ANY), "illegal optional any"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_OPTIONS_ON_ITEM_TEMPLATE),
|
||||
"illegal options on item template"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_TAGGED_ANY), "illegal tagged any"},
|
||||
{ERR_REASON(ASN1_R_ILLEGAL_TIME_VALUE), "illegal time value"},
|
||||
{ERR_REASON(ASN1_R_INTEGER_NOT_ASCII_FORMAT), "integer not ascii format"},
|
||||
{ERR_REASON(ASN1_R_INTEGER_TOO_LARGE_FOR_LONG),
|
||||
"integer too large for long"},
|
||||
{ERR_REASON(ASN1_R_INVALID_BIT_STRING_BITS_LEFT),
|
||||
"invalid bit string bits left"},
|
||||
{ERR_REASON(ASN1_R_INVALID_BMPSTRING_LENGTH), "invalid bmpstring length"},
|
||||
{ERR_REASON(ASN1_R_INVALID_DIGIT), "invalid digit"},
|
||||
{ERR_REASON(ASN1_R_INVALID_MIME_TYPE), "invalid mime type"},
|
||||
{ERR_REASON(ASN1_R_INVALID_MODIFIER), "invalid modifier"},
|
||||
{ERR_REASON(ASN1_R_INVALID_NUMBER), "invalid number"},
|
||||
{ERR_REASON(ASN1_R_INVALID_OBJECT_ENCODING), "invalid object encoding"},
|
||||
{ERR_REASON(ASN1_R_INVALID_SEPARATOR), "invalid separator"},
|
||||
{ERR_REASON(ASN1_R_INVALID_TIME_FORMAT), "invalid time format"},
|
||||
{ERR_REASON(ASN1_R_INVALID_UNIVERSALSTRING_LENGTH),
|
||||
"invalid universalstring length"},
|
||||
{ERR_REASON(ASN1_R_INVALID_UTF8STRING), "invalid utf8string"},
|
||||
{ERR_REASON(ASN1_R_IV_TOO_LARGE), "iv too large"},
|
||||
{ERR_REASON(ASN1_R_LENGTH_ERROR), "length error"},
|
||||
{ERR_REASON(ASN1_R_LIST_ERROR), "list error"},
|
||||
{ERR_REASON(ASN1_R_MIME_NO_CONTENT_TYPE), "mime no content type"},
|
||||
{ERR_REASON(ASN1_R_MIME_PARSE_ERROR), "mime parse error"},
|
||||
{ERR_REASON(ASN1_R_MIME_SIG_PARSE_ERROR), "mime sig parse error"},
|
||||
{ERR_REASON(ASN1_R_MISSING_EOC), "missing eoc"},
|
||||
{ERR_REASON(ASN1_R_MISSING_SECOND_NUMBER), "missing second number"},
|
||||
{ERR_REASON(ASN1_R_MISSING_VALUE), "missing value"},
|
||||
{ERR_REASON(ASN1_R_MSTRING_NOT_UNIVERSAL), "mstring not universal"},
|
||||
{ERR_REASON(ASN1_R_MSTRING_WRONG_TAG), "mstring wrong tag"},
|
||||
{ERR_REASON(ASN1_R_NESTED_ASN1_STRING), "nested asn1 string"},
|
||||
{ERR_REASON(ASN1_R_NON_HEX_CHARACTERS), "non hex characters"},
|
||||
{ERR_REASON(ASN1_R_NOT_ASCII_FORMAT), "not ascii format"},
|
||||
{ERR_REASON(ASN1_R_NOT_ENOUGH_DATA), "not enough data"},
|
||||
{ERR_REASON(ASN1_R_NO_CONTENT_TYPE), "no content type"},
|
||||
{ERR_REASON(ASN1_R_NO_DEFAULT_DIGEST), "no default digest"},
|
||||
{ERR_REASON(ASN1_R_NO_MATCHING_CHOICE_TYPE), "no matching choice type"},
|
||||
{ERR_REASON(ASN1_R_NO_MULTIPART_BODY_FAILURE),
|
||||
"no multipart body failure"},
|
||||
{ERR_REASON(ASN1_R_NO_MULTIPART_BOUNDARY), "no multipart boundary"},
|
||||
{ERR_REASON(ASN1_R_NO_SIG_CONTENT_TYPE), "no sig content type"},
|
||||
{ERR_REASON(ASN1_R_NULL_IS_WRONG_LENGTH), "null is wrong length"},
|
||||
{ERR_REASON(ASN1_R_OBJECT_NOT_ASCII_FORMAT), "object not ascii format"},
|
||||
{ERR_REASON(ASN1_R_ODD_NUMBER_OF_CHARS), "odd number of chars"},
|
||||
{ERR_REASON(ASN1_R_PRIVATE_KEY_HEADER_MISSING),
|
||||
"private key header missing"},
|
||||
{ERR_REASON(ASN1_R_SECOND_NUMBER_TOO_LARGE), "second number too large"},
|
||||
{ERR_REASON(ASN1_R_SEQUENCE_LENGTH_MISMATCH), "sequence length mismatch"},
|
||||
{ERR_REASON(ASN1_R_SEQUENCE_NOT_CONSTRUCTED), "sequence not constructed"},
|
||||
{ERR_REASON(ASN1_R_SEQUENCE_OR_SET_NEEDS_CONFIG),
|
||||
"sequence or set needs config"},
|
||||
{ERR_REASON(ASN1_R_SHORT_LINE), "short line"},
|
||||
{ERR_REASON(ASN1_R_SIG_INVALID_MIME_TYPE), "sig invalid mime type"},
|
||||
{ERR_REASON(ASN1_R_STREAMING_NOT_SUPPORTED), "streaming not supported"},
|
||||
{ERR_REASON(ASN1_R_STRING_TOO_LONG), "string too long"},
|
||||
{ERR_REASON(ASN1_R_STRING_TOO_SHORT), "string too short"},
|
||||
{ERR_REASON(ASN1_R_TAG_VALUE_TOO_HIGH), "tag value too high"},
|
||||
{ERR_REASON(ASN1_R_THE_ASN1_OBJECT_IDENTIFIER_IS_NOT_KNOWN_FOR_THIS_MD),
|
||||
"the asn1 object identifier is not known for this md"},
|
||||
{ERR_REASON(ASN1_R_TIME_NOT_ASCII_FORMAT), "time not ascii format"},
|
||||
{ERR_REASON(ASN1_R_TOO_LONG), "too long"},
|
||||
{ERR_REASON(ASN1_R_TYPE_NOT_CONSTRUCTED), "type not constructed"},
|
||||
{ERR_REASON(ASN1_R_TYPE_NOT_PRIMITIVE), "type not primitive"},
|
||||
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_KEY), "unable to decode rsa key"},
|
||||
{ERR_REASON(ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY),
|
||||
"unable to decode rsa private key"},
|
||||
{ERR_REASON(ASN1_R_UNEXPECTED_EOC), "unexpected eoc"},
|
||||
{ERR_REASON(ASN1_R_UNIVERSALSTRING_IS_WRONG_LENGTH),
|
||||
"universalstring is wrong length"},
|
||||
{ERR_REASON(ASN1_R_UNKNOWN_FORMAT), "unknown format"},
|
||||
{ERR_REASON(ASN1_R_UNKNOWN_MESSAGE_DIGEST_ALGORITHM),
|
||||
"unknown message digest algorithm"},
|
||||
{ERR_REASON(ASN1_R_UNKNOWN_OBJECT_TYPE), "unknown object type"},
|
||||
{ERR_REASON(ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE), "unknown public key type"},
|
||||
{ERR_REASON(ASN1_R_UNKNOWN_SIGNATURE_ALGORITHM),
|
||||
"unknown signature algorithm"},
|
||||
{ERR_REASON(ASN1_R_UNKNOWN_TAG), "unknown tag"},
|
||||
{ERR_REASON(ASN1_R_UNKOWN_FORMAT), "unknown format"},
|
||||
{ERR_REASON(ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE),
|
||||
"unsupported any defined by type"},
|
||||
{ERR_REASON(ASN1_R_UNSUPPORTED_CIPHER), "unsupported cipher"},
|
||||
{ERR_REASON(ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM),
|
||||
"unsupported encryption algorithm"},
|
||||
{ERR_REASON(ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE),
|
||||
"unsupported public key type"},
|
||||
{ERR_REASON(ASN1_R_UNSUPPORTED_TYPE), "unsupported type"},
|
||||
{ERR_REASON(ASN1_R_WRONG_PUBLIC_KEY_TYPE), "wrong public key type"},
|
||||
{ERR_REASON(ASN1_R_WRONG_TAG), "wrong tag"},
|
||||
{ERR_REASON(ASN1_R_WRONG_TYPE), "wrong type"},
|
||||
{0, NULL}
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
void ERR_load_ASN1_strings(void)
|
||||
{
|
||||
{
|
||||
#ifndef OPENSSL_NO_ERR
|
||||
|
||||
if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL)
|
||||
{
|
||||
ERR_load_strings(0,ASN1_str_functs);
|
||||
ERR_load_strings(0,ASN1_str_reasons);
|
||||
}
|
||||
if (ERR_func_error_string(ASN1_str_functs[0].error) == NULL) {
|
||||
ERR_load_strings(0, ASN1_str_functs);
|
||||
ERR_load_strings(0, ASN1_str_reasons);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,421 +62,422 @@
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/asn1_mac.h>
|
||||
|
||||
static int asn1_get_length(const unsigned char **pp,int *inf,long *rl,int max);
|
||||
static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
|
||||
int max);
|
||||
static void asn1_put_length(unsigned char **pp, int length);
|
||||
const char ASN1_version[]="ASN.1" OPENSSL_VERSION_PTEXT;
|
||||
const char ASN1_version[] = "ASN.1" OPENSSL_VERSION_PTEXT;
|
||||
|
||||
static int _asn1_check_infinite_end(const unsigned char **p, long len)
|
||||
{
|
||||
/* If there is 0 or 1 byte left, the length check should pick
|
||||
* things up */
|
||||
if (len <= 0)
|
||||
return(1);
|
||||
else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0))
|
||||
{
|
||||
(*p)+=2;
|
||||
return(1);
|
||||
}
|
||||
return(0);
|
||||
}
|
||||
{
|
||||
/*
|
||||
* If there is 0 or 1 byte left, the length check should pick things up
|
||||
*/
|
||||
if (len <= 0)
|
||||
return (1);
|
||||
else if ((len >= 2) && ((*p)[0] == 0) && ((*p)[1] == 0)) {
|
||||
(*p) += 2;
|
||||
return (1);
|
||||
}
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ASN1_check_infinite_end(unsigned char **p, long len)
|
||||
{
|
||||
return _asn1_check_infinite_end((const unsigned char **)p, len);
|
||||
}
|
||||
{
|
||||
return _asn1_check_infinite_end((const unsigned char **)p, len);
|
||||
}
|
||||
|
||||
int ASN1_const_check_infinite_end(const unsigned char **p, long len)
|
||||
{
|
||||
return _asn1_check_infinite_end(p, len);
|
||||
}
|
||||
|
||||
{
|
||||
return _asn1_check_infinite_end(p, len);
|
||||
}
|
||||
|
||||
int ASN1_get_object(const unsigned char **pp, long *plength, int *ptag,
|
||||
int *pclass, long omax)
|
||||
{
|
||||
int i,ret;
|
||||
long l;
|
||||
const unsigned char *p= *pp;
|
||||
int tag,xclass,inf;
|
||||
long max=omax;
|
||||
int *pclass, long omax)
|
||||
{
|
||||
int i, ret;
|
||||
long l;
|
||||
const unsigned char *p = *pp;
|
||||
int tag, xclass, inf;
|
||||
long max = omax;
|
||||
|
||||
if (!max) goto err;
|
||||
ret=(*p&V_ASN1_CONSTRUCTED);
|
||||
xclass=(*p&V_ASN1_PRIVATE);
|
||||
i= *p&V_ASN1_PRIMITIVE_TAG;
|
||||
if (i == V_ASN1_PRIMITIVE_TAG)
|
||||
{ /* high-tag */
|
||||
p++;
|
||||
if (--max == 0) goto err;
|
||||
l=0;
|
||||
while (*p&0x80)
|
||||
{
|
||||
l<<=7L;
|
||||
l|= *(p++)&0x7f;
|
||||
if (--max == 0) goto err;
|
||||
if (l > (INT_MAX >> 7L)) goto err;
|
||||
}
|
||||
l<<=7L;
|
||||
l|= *(p++)&0x7f;
|
||||
tag=(int)l;
|
||||
if (--max == 0) goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
tag=i;
|
||||
p++;
|
||||
if (--max == 0) goto err;
|
||||
}
|
||||
*ptag=tag;
|
||||
*pclass=xclass;
|
||||
if (!asn1_get_length(&p,&inf,plength,(int)max)) goto err;
|
||||
if (!max)
|
||||
goto err;
|
||||
ret = (*p & V_ASN1_CONSTRUCTED);
|
||||
xclass = (*p & V_ASN1_PRIVATE);
|
||||
i = *p & V_ASN1_PRIMITIVE_TAG;
|
||||
if (i == V_ASN1_PRIMITIVE_TAG) { /* high-tag */
|
||||
p++;
|
||||
if (--max == 0)
|
||||
goto err;
|
||||
l = 0;
|
||||
while (*p & 0x80) {
|
||||
l <<= 7L;
|
||||
l |= *(p++) & 0x7f;
|
||||
if (--max == 0)
|
||||
goto err;
|
||||
if (l > (INT_MAX >> 7L))
|
||||
goto err;
|
||||
}
|
||||
l <<= 7L;
|
||||
l |= *(p++) & 0x7f;
|
||||
tag = (int)l;
|
||||
if (--max == 0)
|
||||
goto err;
|
||||
} else {
|
||||
tag = i;
|
||||
p++;
|
||||
if (--max == 0)
|
||||
goto err;
|
||||
}
|
||||
*ptag = tag;
|
||||
*pclass = xclass;
|
||||
if (!asn1_get_length(&p, &inf, plength, (int)max))
|
||||
goto err;
|
||||
|
||||
if (inf && !(ret & V_ASN1_CONSTRUCTED))
|
||||
goto err;
|
||||
|
||||
#if 0
|
||||
fprintf(stderr,"p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n",
|
||||
(int)p,*plength,omax,(int)*pp,(int)(p+ *plength),
|
||||
(int)(omax+ *pp));
|
||||
fprintf(stderr, "p=%d + *plength=%ld > omax=%ld + *pp=%d (%d > %d)\n",
|
||||
(int)p, *plength, omax, (int)*pp, (int)(p + *plength),
|
||||
(int)(omax + *pp));
|
||||
|
||||
#endif
|
||||
if (*plength > (omax - (p - *pp)))
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_GET_OBJECT,ASN1_R_TOO_LONG);
|
||||
/* Set this so that even if things are not long enough
|
||||
* the values are set correctly */
|
||||
ret|=0x80;
|
||||
}
|
||||
*pp=p;
|
||||
return(ret|inf);
|
||||
err:
|
||||
ASN1err(ASN1_F_ASN1_GET_OBJECT,ASN1_R_HEADER_TOO_LONG);
|
||||
return(0x80);
|
||||
}
|
||||
if (*plength > (omax - (p - *pp))) {
|
||||
ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_TOO_LONG);
|
||||
/*
|
||||
* Set this so that even if things are not long enough the values are
|
||||
* set correctly
|
||||
*/
|
||||
ret |= 0x80;
|
||||
}
|
||||
*pp = p;
|
||||
return (ret | inf);
|
||||
err:
|
||||
ASN1err(ASN1_F_ASN1_GET_OBJECT, ASN1_R_HEADER_TOO_LONG);
|
||||
return (0x80);
|
||||
}
|
||||
|
||||
static int asn1_get_length(const unsigned char **pp, int *inf, long *rl, int max)
|
||||
{
|
||||
const unsigned char *p= *pp;
|
||||
unsigned long ret=0;
|
||||
unsigned int i;
|
||||
static int asn1_get_length(const unsigned char **pp, int *inf, long *rl,
|
||||
int max)
|
||||
{
|
||||
const unsigned char *p = *pp;
|
||||
unsigned long ret = 0;
|
||||
unsigned int i;
|
||||
|
||||
if (max-- < 1) return(0);
|
||||
if (*p == 0x80)
|
||||
{
|
||||
*inf=1;
|
||||
ret=0;
|
||||
p++;
|
||||
}
|
||||
else
|
||||
{
|
||||
*inf=0;
|
||||
i= *p&0x7f;
|
||||
if (*(p++) & 0x80)
|
||||
{
|
||||
if (i > sizeof(long))
|
||||
return 0;
|
||||
if (max-- == 0) return(0);
|
||||
while (i-- > 0)
|
||||
{
|
||||
ret<<=8L;
|
||||
ret|= *(p++);
|
||||
if (max-- == 0) return(0);
|
||||
}
|
||||
}
|
||||
else
|
||||
ret=i;
|
||||
}
|
||||
if (ret > LONG_MAX)
|
||||
return 0;
|
||||
*pp=p;
|
||||
*rl=(long)ret;
|
||||
return(1);
|
||||
}
|
||||
if (max-- < 1)
|
||||
return (0);
|
||||
if (*p == 0x80) {
|
||||
*inf = 1;
|
||||
ret = 0;
|
||||
p++;
|
||||
} else {
|
||||
*inf = 0;
|
||||
i = *p & 0x7f;
|
||||
if (*(p++) & 0x80) {
|
||||
if (i > sizeof(long))
|
||||
return 0;
|
||||
if (max-- == 0)
|
||||
return (0);
|
||||
while (i-- > 0) {
|
||||
ret <<= 8L;
|
||||
ret |= *(p++);
|
||||
if (max-- == 0)
|
||||
return (0);
|
||||
}
|
||||
} else
|
||||
ret = i;
|
||||
}
|
||||
if (ret > LONG_MAX)
|
||||
return 0;
|
||||
*pp = p;
|
||||
*rl = (long)ret;
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* class 0 is constructed
|
||||
* constructed == 2 for indefinite length constructed */
|
||||
/*
|
||||
* class 0 is constructed constructed == 2 for indefinite length constructed
|
||||
*/
|
||||
void ASN1_put_object(unsigned char **pp, int constructed, int length, int tag,
|
||||
int xclass)
|
||||
{
|
||||
unsigned char *p= *pp;
|
||||
int i, ttag;
|
||||
int xclass)
|
||||
{
|
||||
unsigned char *p = *pp;
|
||||
int i, ttag;
|
||||
|
||||
i=(constructed)?V_ASN1_CONSTRUCTED:0;
|
||||
i|=(xclass&V_ASN1_PRIVATE);
|
||||
if (tag < 31)
|
||||
*(p++)=i|(tag&V_ASN1_PRIMITIVE_TAG);
|
||||
else
|
||||
{
|
||||
*(p++)=i|V_ASN1_PRIMITIVE_TAG;
|
||||
for(i = 0, ttag = tag; ttag > 0; i++) ttag >>=7;
|
||||
ttag = i;
|
||||
while(i-- > 0)
|
||||
{
|
||||
p[i] = tag & 0x7f;
|
||||
if(i != (ttag - 1)) p[i] |= 0x80;
|
||||
tag >>= 7;
|
||||
}
|
||||
p += ttag;
|
||||
}
|
||||
if (constructed == 2)
|
||||
*(p++)=0x80;
|
||||
else
|
||||
asn1_put_length(&p,length);
|
||||
*pp=p;
|
||||
}
|
||||
i = (constructed) ? V_ASN1_CONSTRUCTED : 0;
|
||||
i |= (xclass & V_ASN1_PRIVATE);
|
||||
if (tag < 31)
|
||||
*(p++) = i | (tag & V_ASN1_PRIMITIVE_TAG);
|
||||
else {
|
||||
*(p++) = i | V_ASN1_PRIMITIVE_TAG;
|
||||
for (i = 0, ttag = tag; ttag > 0; i++)
|
||||
ttag >>= 7;
|
||||
ttag = i;
|
||||
while (i-- > 0) {
|
||||
p[i] = tag & 0x7f;
|
||||
if (i != (ttag - 1))
|
||||
p[i] |= 0x80;
|
||||
tag >>= 7;
|
||||
}
|
||||
p += ttag;
|
||||
}
|
||||
if (constructed == 2)
|
||||
*(p++) = 0x80;
|
||||
else
|
||||
asn1_put_length(&p, length);
|
||||
*pp = p;
|
||||
}
|
||||
|
||||
int ASN1_put_eoc(unsigned char **pp)
|
||||
{
|
||||
unsigned char *p = *pp;
|
||||
*p++ = 0;
|
||||
*p++ = 0;
|
||||
*pp = p;
|
||||
return 2;
|
||||
}
|
||||
{
|
||||
unsigned char *p = *pp;
|
||||
*p++ = 0;
|
||||
*p++ = 0;
|
||||
*pp = p;
|
||||
return 2;
|
||||
}
|
||||
|
||||
static void asn1_put_length(unsigned char **pp, int length)
|
||||
{
|
||||
unsigned char *p= *pp;
|
||||
int i,l;
|
||||
if (length <= 127)
|
||||
*(p++)=(unsigned char)length;
|
||||
else
|
||||
{
|
||||
l=length;
|
||||
for (i=0; l > 0; i++)
|
||||
l>>=8;
|
||||
*(p++)=i|0x80;
|
||||
l=i;
|
||||
while (i-- > 0)
|
||||
{
|
||||
p[i]=length&0xff;
|
||||
length>>=8;
|
||||
}
|
||||
p+=l;
|
||||
}
|
||||
*pp=p;
|
||||
}
|
||||
{
|
||||
unsigned char *p = *pp;
|
||||
int i, l;
|
||||
if (length <= 127)
|
||||
*(p++) = (unsigned char)length;
|
||||
else {
|
||||
l = length;
|
||||
for (i = 0; l > 0; i++)
|
||||
l >>= 8;
|
||||
*(p++) = i | 0x80;
|
||||
l = i;
|
||||
while (i-- > 0) {
|
||||
p[i] = length & 0xff;
|
||||
length >>= 8;
|
||||
}
|
||||
p += l;
|
||||
}
|
||||
*pp = p;
|
||||
}
|
||||
|
||||
int ASN1_object_size(int constructed, int length, int tag)
|
||||
{
|
||||
int ret;
|
||||
{
|
||||
int ret;
|
||||
|
||||
ret=length;
|
||||
ret++;
|
||||
if (tag >= 31)
|
||||
{
|
||||
while (tag > 0)
|
||||
{
|
||||
tag>>=7;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
if (constructed == 2)
|
||||
return ret + 3;
|
||||
ret++;
|
||||
if (length > 127)
|
||||
{
|
||||
while (length > 0)
|
||||
{
|
||||
length>>=8;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
ret = length;
|
||||
ret++;
|
||||
if (tag >= 31) {
|
||||
while (tag > 0) {
|
||||
tag >>= 7;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
if (constructed == 2)
|
||||
return ret + 3;
|
||||
ret++;
|
||||
if (length > 127) {
|
||||
while (length > 0) {
|
||||
length >>= 8;
|
||||
ret++;
|
||||
}
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
static int _asn1_Finish(ASN1_const_CTX *c)
|
||||
{
|
||||
if ((c->inf == (1|V_ASN1_CONSTRUCTED)) && (!c->eos))
|
||||
{
|
||||
if (!ASN1_const_check_infinite_end(&c->p,c->slen))
|
||||
{
|
||||
c->error=ERR_R_MISSING_ASN1_EOS;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
if ( ((c->slen != 0) && !(c->inf & 1)) ||
|
||||
((c->slen < 0) && (c->inf & 1)))
|
||||
{
|
||||
c->error=ERR_R_ASN1_LENGTH_MISMATCH;
|
||||
return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
{
|
||||
if ((c->inf == (1 | V_ASN1_CONSTRUCTED)) && (!c->eos)) {
|
||||
if (!ASN1_const_check_infinite_end(&c->p, c->slen)) {
|
||||
c->error = ERR_R_MISSING_ASN1_EOS;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
if (((c->slen != 0) && !(c->inf & 1)) || ((c->slen < 0) && (c->inf & 1))) {
|
||||
c->error = ERR_R_ASN1_LENGTH_MISMATCH;
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
int asn1_Finish(ASN1_CTX *c)
|
||||
{
|
||||
return _asn1_Finish((ASN1_const_CTX *)c);
|
||||
}
|
||||
{
|
||||
return _asn1_Finish((ASN1_const_CTX *)c);
|
||||
}
|
||||
|
||||
int asn1_const_Finish(ASN1_const_CTX *c)
|
||||
{
|
||||
return _asn1_Finish(c);
|
||||
}
|
||||
{
|
||||
return _asn1_Finish(c);
|
||||
}
|
||||
|
||||
int asn1_GetSequence(ASN1_const_CTX *c, long *length)
|
||||
{
|
||||
const unsigned char *q;
|
||||
{
|
||||
const unsigned char *q;
|
||||
|
||||
q=c->p;
|
||||
c->inf=ASN1_get_object(&(c->p),&(c->slen),&(c->tag),&(c->xclass),
|
||||
*length);
|
||||
if (c->inf & 0x80)
|
||||
{
|
||||
c->error=ERR_R_BAD_GET_ASN1_OBJECT_CALL;
|
||||
return(0);
|
||||
}
|
||||
if (c->tag != V_ASN1_SEQUENCE)
|
||||
{
|
||||
c->error=ERR_R_EXPECTING_AN_ASN1_SEQUENCE;
|
||||
return(0);
|
||||
}
|
||||
(*length)-=(c->p-q);
|
||||
if (c->max && (*length < 0))
|
||||
{
|
||||
c->error=ERR_R_ASN1_LENGTH_MISMATCH;
|
||||
return(0);
|
||||
}
|
||||
if (c->inf == (1|V_ASN1_CONSTRUCTED))
|
||||
c->slen= *length+ *(c->pp)-c->p;
|
||||
c->eos=0;
|
||||
return(1);
|
||||
}
|
||||
q = c->p;
|
||||
c->inf = ASN1_get_object(&(c->p), &(c->slen), &(c->tag), &(c->xclass),
|
||||
*length);
|
||||
if (c->inf & 0x80) {
|
||||
c->error = ERR_R_BAD_GET_ASN1_OBJECT_CALL;
|
||||
return (0);
|
||||
}
|
||||
if (c->tag != V_ASN1_SEQUENCE) {
|
||||
c->error = ERR_R_EXPECTING_AN_ASN1_SEQUENCE;
|
||||
return (0);
|
||||
}
|
||||
(*length) -= (c->p - q);
|
||||
if (c->max && (*length < 0)) {
|
||||
c->error = ERR_R_ASN1_LENGTH_MISMATCH;
|
||||
return (0);
|
||||
}
|
||||
if (c->inf == (1 | V_ASN1_CONSTRUCTED))
|
||||
c->slen = *length + *(c->pp) - c->p;
|
||||
c->eos = 0;
|
||||
return (1);
|
||||
}
|
||||
|
||||
int ASN1_STRING_copy(ASN1_STRING *dst, const ASN1_STRING *str)
|
||||
{
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
dst->type = str->type;
|
||||
if (!ASN1_STRING_set(dst,str->data,str->length))
|
||||
return 0;
|
||||
dst->flags = str->flags;
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
if (str == NULL)
|
||||
return 0;
|
||||
dst->type = str->type;
|
||||
if (!ASN1_STRING_set(dst, str->data, str->length))
|
||||
return 0;
|
||||
dst->flags = str->flags;
|
||||
return 1;
|
||||
}
|
||||
|
||||
ASN1_STRING *ASN1_STRING_dup(const ASN1_STRING *str)
|
||||
{
|
||||
ASN1_STRING *ret;
|
||||
if (!str)
|
||||
return NULL;
|
||||
ret=ASN1_STRING_new();
|
||||
if (!ret)
|
||||
return NULL;
|
||||
if (!ASN1_STRING_copy(ret,str))
|
||||
{
|
||||
ASN1_STRING_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
{
|
||||
ASN1_STRING *ret;
|
||||
if (!str)
|
||||
return NULL;
|
||||
ret = ASN1_STRING_new();
|
||||
if (!ret)
|
||||
return NULL;
|
||||
if (!ASN1_STRING_copy(ret, str)) {
|
||||
ASN1_STRING_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int ASN1_STRING_set(ASN1_STRING *str, const void *_data, int len)
|
||||
{
|
||||
unsigned char *c;
|
||||
const char *data=_data;
|
||||
{
|
||||
unsigned char *c;
|
||||
const char *data = _data;
|
||||
|
||||
if (len < 0)
|
||||
{
|
||||
if (data == NULL)
|
||||
return(0);
|
||||
else
|
||||
len=strlen(data);
|
||||
}
|
||||
if ((str->length < len) || (str->data == NULL))
|
||||
{
|
||||
c=str->data;
|
||||
if (c == NULL)
|
||||
str->data=OPENSSL_malloc(len+1);
|
||||
else
|
||||
str->data=OPENSSL_realloc(c,len+1);
|
||||
if (len < 0) {
|
||||
if (data == NULL)
|
||||
return (0);
|
||||
else
|
||||
len = strlen(data);
|
||||
}
|
||||
if ((str->length < len) || (str->data == NULL)) {
|
||||
c = str->data;
|
||||
if (c == NULL)
|
||||
str->data = OPENSSL_malloc(len + 1);
|
||||
else
|
||||
str->data = OPENSSL_realloc(c, len + 1);
|
||||
|
||||
if (str->data == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_STRING_SET,ERR_R_MALLOC_FAILURE);
|
||||
str->data=c;
|
||||
return(0);
|
||||
}
|
||||
}
|
||||
str->length=len;
|
||||
if (data != NULL)
|
||||
{
|
||||
memcpy(str->data,data,len);
|
||||
/* an allowance for strings :-) */
|
||||
str->data[len]='\0';
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
if (str->data == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_STRING_SET, ERR_R_MALLOC_FAILURE);
|
||||
str->data = c;
|
||||
return (0);
|
||||
}
|
||||
}
|
||||
str->length = len;
|
||||
if (data != NULL) {
|
||||
memcpy(str->data, data, len);
|
||||
/* an allowance for strings :-) */
|
||||
str->data[len] = '\0';
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
void ASN1_STRING_set0(ASN1_STRING *str, void *data, int len)
|
||||
{
|
||||
if (str->data)
|
||||
OPENSSL_free(str->data);
|
||||
str->data = data;
|
||||
str->length = len;
|
||||
}
|
||||
{
|
||||
if (str->data)
|
||||
OPENSSL_free(str->data);
|
||||
str->data = data;
|
||||
str->length = len;
|
||||
}
|
||||
|
||||
ASN1_STRING *ASN1_STRING_new(void)
|
||||
{
|
||||
return(ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
|
||||
}
|
||||
|
||||
{
|
||||
return (ASN1_STRING_type_new(V_ASN1_OCTET_STRING));
|
||||
}
|
||||
|
||||
ASN1_STRING *ASN1_STRING_type_new(int type)
|
||||
{
|
||||
ASN1_STRING *ret;
|
||||
{
|
||||
ASN1_STRING *ret;
|
||||
|
||||
ret=(ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
|
||||
if (ret == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW,ERR_R_MALLOC_FAILURE);
|
||||
return(NULL);
|
||||
}
|
||||
ret->length=0;
|
||||
ret->type=type;
|
||||
ret->data=NULL;
|
||||
ret->flags=0;
|
||||
return(ret);
|
||||
}
|
||||
ret = (ASN1_STRING *)OPENSSL_malloc(sizeof(ASN1_STRING));
|
||||
if (ret == NULL) {
|
||||
ASN1err(ASN1_F_ASN1_STRING_TYPE_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
ret->length = 0;
|
||||
ret->type = type;
|
||||
ret->data = NULL;
|
||||
ret->flags = 0;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void ASN1_STRING_free(ASN1_STRING *a)
|
||||
{
|
||||
if (a == NULL) return;
|
||||
if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
|
||||
OPENSSL_free(a->data);
|
||||
OPENSSL_free(a);
|
||||
}
|
||||
{
|
||||
if (a == NULL)
|
||||
return;
|
||||
if (a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
|
||||
OPENSSL_free(a->data);
|
||||
OPENSSL_free(a);
|
||||
}
|
||||
|
||||
void ASN1_STRING_clear_free(ASN1_STRING *a)
|
||||
{
|
||||
if (a && a->data && !(a->flags & ASN1_STRING_FLAG_NDEF))
|
||||
OPENSSL_cleanse(a->data, a->length);
|
||||
ASN1_STRING_free(a);
|
||||
}
|
||||
|
||||
int ASN1_STRING_cmp(const ASN1_STRING *a, const ASN1_STRING *b)
|
||||
{
|
||||
int i;
|
||||
{
|
||||
int i;
|
||||
|
||||
i=(a->length-b->length);
|
||||
if (i == 0)
|
||||
{
|
||||
i=memcmp(a->data,b->data,a->length);
|
||||
if (i == 0)
|
||||
return(a->type-b->type);
|
||||
else
|
||||
return(i);
|
||||
}
|
||||
else
|
||||
return(i);
|
||||
}
|
||||
i = (a->length - b->length);
|
||||
if (i == 0) {
|
||||
i = memcmp(a->data, b->data, a->length);
|
||||
if (i == 0)
|
||||
return (a->type - b->type);
|
||||
else
|
||||
return (i);
|
||||
} else
|
||||
return (i);
|
||||
}
|
||||
|
||||
void asn1_add_error(const unsigned char *address, int offset)
|
||||
{
|
||||
char buf1[DECIMAL_SIZE(address)+1],buf2[DECIMAL_SIZE(offset)+1];
|
||||
{
|
||||
char buf1[DECIMAL_SIZE(address) + 1], buf2[DECIMAL_SIZE(offset) + 1];
|
||||
|
||||
BIO_snprintf(buf1,sizeof buf1,"%lu",(unsigned long)address);
|
||||
BIO_snprintf(buf2,sizeof buf2,"%d",offset);
|
||||
ERR_add_error_data(4,"address=",buf1," offset=",buf2);
|
||||
}
|
||||
BIO_snprintf(buf1, sizeof buf1, "%lu", (unsigned long)address);
|
||||
BIO_snprintf(buf2, sizeof buf2, "%d", offset);
|
||||
ERR_add_error_data(4, "address=", buf1, " offset=", buf2);
|
||||
}
|
||||
|
||||
int ASN1_STRING_length(const ASN1_STRING *x)
|
||||
{ return M_ASN1_STRING_length(x); }
|
||||
{
|
||||
return M_ASN1_STRING_length(x);
|
||||
}
|
||||
|
||||
void ASN1_STRING_length_set(ASN1_STRING *x, int len)
|
||||
{ M_ASN1_STRING_length_set(x, len); return; }
|
||||
{
|
||||
M_ASN1_STRING_length_set(x, len);
|
||||
return;
|
||||
}
|
||||
|
||||
int ASN1_STRING_type(ASN1_STRING *x)
|
||||
{ return M_ASN1_STRING_type(x); }
|
||||
{
|
||||
return M_ASN1_STRING_type(x);
|
||||
}
|
||||
|
||||
unsigned char * ASN1_STRING_data(ASN1_STRING *x)
|
||||
{ return M_ASN1_STRING_data(x); }
|
||||
unsigned char *ASN1_STRING_data(ASN1_STRING *x)
|
||||
{
|
||||
return M_ASN1_STRING_data(x);
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* asn1t.h */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2006.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2006.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2006 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -60,86 +61,72 @@
|
||||
|
||||
/* ASN1 print context structure */
|
||||
|
||||
struct asn1_pctx_st
|
||||
{
|
||||
unsigned long flags;
|
||||
unsigned long nm_flags;
|
||||
unsigned long cert_flags;
|
||||
unsigned long oid_flags;
|
||||
unsigned long str_flags;
|
||||
} /* ASN1_PCTX */;
|
||||
struct asn1_pctx_st {
|
||||
unsigned long flags;
|
||||
unsigned long nm_flags;
|
||||
unsigned long cert_flags;
|
||||
unsigned long oid_flags;
|
||||
unsigned long str_flags;
|
||||
} /* ASN1_PCTX */ ;
|
||||
|
||||
/* ASN1 public key method structure */
|
||||
|
||||
struct evp_pkey_asn1_method_st
|
||||
{
|
||||
int pkey_id;
|
||||
int pkey_base_id;
|
||||
unsigned long pkey_flags;
|
||||
struct evp_pkey_asn1_method_st {
|
||||
int pkey_id;
|
||||
int pkey_base_id;
|
||||
unsigned long pkey_flags;
|
||||
char *pem_str;
|
||||
char *info;
|
||||
int (*pub_decode) (EVP_PKEY *pk, X509_PUBKEY *pub);
|
||||
int (*pub_encode) (X509_PUBKEY *pub, const EVP_PKEY *pk);
|
||||
int (*pub_cmp) (const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
int (*pub_print) (BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx);
|
||||
int (*priv_decode) (EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
|
||||
int (*priv_encode) (PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
|
||||
int (*priv_print) (BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx);
|
||||
int (*pkey_size) (const EVP_PKEY *pk);
|
||||
int (*pkey_bits) (const EVP_PKEY *pk);
|
||||
int (*param_decode) (EVP_PKEY *pkey,
|
||||
const unsigned char **pder, int derlen);
|
||||
int (*param_encode) (const EVP_PKEY *pkey, unsigned char **pder);
|
||||
int (*param_missing) (const EVP_PKEY *pk);
|
||||
int (*param_copy) (EVP_PKEY *to, const EVP_PKEY *from);
|
||||
int (*param_cmp) (const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
int (*param_print) (BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx);
|
||||
int (*sig_print) (BIO *out,
|
||||
const X509_ALGOR *sigalg, const ASN1_STRING *sig,
|
||||
int indent, ASN1_PCTX *pctx);
|
||||
void (*pkey_free) (EVP_PKEY *pkey);
|
||||
int (*pkey_ctrl) (EVP_PKEY *pkey, int op, long arg1, void *arg2);
|
||||
/* Legacy functions for old PEM */
|
||||
int (*old_priv_decode) (EVP_PKEY *pkey,
|
||||
const unsigned char **pder, int derlen);
|
||||
int (*old_priv_encode) (const EVP_PKEY *pkey, unsigned char **pder);
|
||||
/* Custom ASN1 signature verification */
|
||||
int (*item_verify) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
|
||||
X509_ALGOR *a, ASN1_BIT_STRING *sig, EVP_PKEY *pkey);
|
||||
int (*item_sign) (EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
|
||||
X509_ALGOR *alg1, X509_ALGOR *alg2,
|
||||
ASN1_BIT_STRING *sig);
|
||||
} /* EVP_PKEY_ASN1_METHOD */ ;
|
||||
|
||||
char *pem_str;
|
||||
char *info;
|
||||
|
||||
int (*pub_decode)(EVP_PKEY *pk, X509_PUBKEY *pub);
|
||||
int (*pub_encode)(X509_PUBKEY *pub, const EVP_PKEY *pk);
|
||||
int (*pub_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
int (*pub_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx);
|
||||
|
||||
int (*priv_decode)(EVP_PKEY *pk, PKCS8_PRIV_KEY_INFO *p8inf);
|
||||
int (*priv_encode)(PKCS8_PRIV_KEY_INFO *p8, const EVP_PKEY *pk);
|
||||
int (*priv_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx);
|
||||
|
||||
int (*pkey_size)(const EVP_PKEY *pk);
|
||||
int (*pkey_bits)(const EVP_PKEY *pk);
|
||||
|
||||
int (*param_decode)(EVP_PKEY *pkey,
|
||||
const unsigned char **pder, int derlen);
|
||||
int (*param_encode)(const EVP_PKEY *pkey, unsigned char **pder);
|
||||
int (*param_missing)(const EVP_PKEY *pk);
|
||||
int (*param_copy)(EVP_PKEY *to, const EVP_PKEY *from);
|
||||
int (*param_cmp)(const EVP_PKEY *a, const EVP_PKEY *b);
|
||||
int (*param_print)(BIO *out, const EVP_PKEY *pkey, int indent,
|
||||
ASN1_PCTX *pctx);
|
||||
int (*sig_print)(BIO *out,
|
||||
const X509_ALGOR *sigalg, const ASN1_STRING *sig,
|
||||
int indent, ASN1_PCTX *pctx);
|
||||
|
||||
|
||||
void (*pkey_free)(EVP_PKEY *pkey);
|
||||
int (*pkey_ctrl)(EVP_PKEY *pkey, int op, long arg1, void *arg2);
|
||||
|
||||
/* Legacy functions for old PEM */
|
||||
|
||||
int (*old_priv_decode)(EVP_PKEY *pkey,
|
||||
const unsigned char **pder, int derlen);
|
||||
int (*old_priv_encode)(const EVP_PKEY *pkey, unsigned char **pder);
|
||||
/* Custom ASN1 signature verification */
|
||||
int (*item_verify)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
|
||||
X509_ALGOR *a, ASN1_BIT_STRING *sig,
|
||||
EVP_PKEY *pkey);
|
||||
int (*item_sign)(EVP_MD_CTX *ctx, const ASN1_ITEM *it, void *asn,
|
||||
X509_ALGOR *alg1, X509_ALGOR *alg2,
|
||||
ASN1_BIT_STRING *sig);
|
||||
|
||||
} /* EVP_PKEY_ASN1_METHOD */;
|
||||
|
||||
/* Method to handle CRL access.
|
||||
* In general a CRL could be very large (several Mb) and can consume large
|
||||
* amounts of resources if stored in memory by multiple processes.
|
||||
* This method allows general CRL operations to be redirected to more
|
||||
* efficient callbacks: for example a CRL entry database.
|
||||
/*
|
||||
* Method to handle CRL access. In general a CRL could be very large (several
|
||||
* Mb) and can consume large amounts of resources if stored in memory by
|
||||
* multiple processes. This method allows general CRL operations to be
|
||||
* redirected to more efficient callbacks: for example a CRL entry database.
|
||||
*/
|
||||
|
||||
#define X509_CRL_METHOD_DYNAMIC 1
|
||||
#define X509_CRL_METHOD_DYNAMIC 1
|
||||
|
||||
struct x509_crl_method_st
|
||||
{
|
||||
int flags;
|
||||
int (*crl_init)(X509_CRL *crl);
|
||||
int (*crl_free)(X509_CRL *crl);
|
||||
int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
|
||||
ASN1_INTEGER *ser, X509_NAME *issuer);
|
||||
int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk);
|
||||
};
|
||||
struct x509_crl_method_st {
|
||||
int flags;
|
||||
int (*crl_init) (X509_CRL *crl);
|
||||
int (*crl_free) (X509_CRL *crl);
|
||||
int (*crl_lookup) (X509_CRL *crl, X509_REVOKED **ret,
|
||||
ASN1_INTEGER *ser, X509_NAME *issuer);
|
||||
int (*crl_verify) (X509_CRL *crl, EVP_PKEY *pk);
|
||||
};
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,376 +62,354 @@
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
static int asn1_print_info(BIO *bp, int tag, int xclass,int constructed,
|
||||
int indent);
|
||||
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
|
||||
int offset, int depth, int indent, int dump);
|
||||
#ifndef ASN1_PARSE_MAXDEPTH
|
||||
#define ASN1_PARSE_MAXDEPTH 128
|
||||
#endif
|
||||
|
||||
static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
|
||||
int indent)
|
||||
{
|
||||
static const char fmt[]="%-18s";
|
||||
char str[128];
|
||||
const char *p;
|
||||
int indent);
|
||||
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
|
||||
int offset, int depth, int indent, int dump);
|
||||
static int asn1_print_info(BIO *bp, int tag, int xclass, int constructed,
|
||||
int indent)
|
||||
{
|
||||
static const char fmt[] = "%-18s";
|
||||
char str[128];
|
||||
const char *p;
|
||||
|
||||
if (constructed & V_ASN1_CONSTRUCTED)
|
||||
p="cons: ";
|
||||
else
|
||||
p="prim: ";
|
||||
if (BIO_write(bp,p,6) < 6) goto err;
|
||||
BIO_indent(bp,indent,128);
|
||||
if (constructed & V_ASN1_CONSTRUCTED)
|
||||
p = "cons: ";
|
||||
else
|
||||
p = "prim: ";
|
||||
if (BIO_write(bp, p, 6) < 6)
|
||||
goto err;
|
||||
BIO_indent(bp, indent, 128);
|
||||
|
||||
p=str;
|
||||
if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
|
||||
BIO_snprintf(str,sizeof str,"priv [ %d ] ",tag);
|
||||
else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
|
||||
BIO_snprintf(str,sizeof str,"cont [ %d ]",tag);
|
||||
else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
|
||||
BIO_snprintf(str,sizeof str,"appl [ %d ]",tag);
|
||||
else if (tag > 30)
|
||||
BIO_snprintf(str,sizeof str,"<ASN1 %d>",tag);
|
||||
else
|
||||
p = ASN1_tag2str(tag);
|
||||
p = str;
|
||||
if ((xclass & V_ASN1_PRIVATE) == V_ASN1_PRIVATE)
|
||||
BIO_snprintf(str, sizeof str, "priv [ %d ] ", tag);
|
||||
else if ((xclass & V_ASN1_CONTEXT_SPECIFIC) == V_ASN1_CONTEXT_SPECIFIC)
|
||||
BIO_snprintf(str, sizeof str, "cont [ %d ]", tag);
|
||||
else if ((xclass & V_ASN1_APPLICATION) == V_ASN1_APPLICATION)
|
||||
BIO_snprintf(str, sizeof str, "appl [ %d ]", tag);
|
||||
else if (tag > 30)
|
||||
BIO_snprintf(str, sizeof str, "<ASN1 %d>", tag);
|
||||
else
|
||||
p = ASN1_tag2str(tag);
|
||||
|
||||
if (BIO_printf(bp,fmt,p) <= 0)
|
||||
goto err;
|
||||
return(1);
|
||||
err:
|
||||
return(0);
|
||||
}
|
||||
if (BIO_printf(bp, fmt, p) <= 0)
|
||||
goto err;
|
||||
return (1);
|
||||
err:
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ASN1_parse(BIO *bp, const unsigned char *pp, long len, int indent)
|
||||
{
|
||||
return(asn1_parse2(bp,&pp,len,0,0,indent,0));
|
||||
}
|
||||
{
|
||||
return (asn1_parse2(bp, &pp, len, 0, 0, indent, 0));
|
||||
}
|
||||
|
||||
int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent, int dump)
|
||||
{
|
||||
return(asn1_parse2(bp,&pp,len,0,0,indent,dump));
|
||||
}
|
||||
int ASN1_parse_dump(BIO *bp, const unsigned char *pp, long len, int indent,
|
||||
int dump)
|
||||
{
|
||||
return (asn1_parse2(bp, &pp, len, 0, 0, indent, dump));
|
||||
}
|
||||
|
||||
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length, int offset,
|
||||
int depth, int indent, int dump)
|
||||
{
|
||||
const unsigned char *p,*ep,*tot,*op,*opp;
|
||||
long len;
|
||||
int tag,xclass,ret=0;
|
||||
int nl,hl,j,r;
|
||||
ASN1_OBJECT *o=NULL;
|
||||
ASN1_OCTET_STRING *os=NULL;
|
||||
/* ASN1_BMPSTRING *bmp=NULL;*/
|
||||
int dump_indent;
|
||||
static int asn1_parse2(BIO *bp, const unsigned char **pp, long length,
|
||||
int offset, int depth, int indent, int dump)
|
||||
{
|
||||
const unsigned char *p, *ep, *tot, *op, *opp;
|
||||
long len;
|
||||
int tag, xclass, ret = 0;
|
||||
int nl, hl, j, r;
|
||||
ASN1_OBJECT *o = NULL;
|
||||
ASN1_OCTET_STRING *os = NULL;
|
||||
/* ASN1_BMPSTRING *bmp=NULL; */
|
||||
int dump_indent;
|
||||
|
||||
#if 0
|
||||
dump_indent = indent;
|
||||
dump_indent = indent;
|
||||
#else
|
||||
dump_indent = 6; /* Because we know BIO_dump_indent() */
|
||||
dump_indent = 6; /* Because we know BIO_dump_indent() */
|
||||
#endif
|
||||
p= *pp;
|
||||
tot=p+length;
|
||||
op=p-1;
|
||||
while ((p < tot) && (op < p))
|
||||
{
|
||||
op=p;
|
||||
j=ASN1_get_object(&p,&len,&tag,&xclass,length);
|
||||
|
||||
if (depth > ASN1_PARSE_MAXDEPTH) {
|
||||
BIO_puts(bp, "BAD RECURSION DEPTH\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
p = *pp;
|
||||
tot = p + length;
|
||||
op = p - 1;
|
||||
while ((p < tot) && (op < p)) {
|
||||
op = p;
|
||||
j = ASN1_get_object(&p, &len, &tag, &xclass, length);
|
||||
#ifdef LINT
|
||||
j=j;
|
||||
j = j;
|
||||
#endif
|
||||
if (j & 0x80)
|
||||
{
|
||||
if (BIO_write(bp,"Error in encoding\n",18) <= 0)
|
||||
goto end;
|
||||
ret=0;
|
||||
goto end;
|
||||
}
|
||||
hl=(p-op);
|
||||
length-=hl;
|
||||
/* if j == 0x21 it is a constructed indefinite length object */
|
||||
if (BIO_printf(bp,"%5ld:",(long)offset+(long)(op- *pp))
|
||||
<= 0) goto end;
|
||||
if (j & 0x80) {
|
||||
if (BIO_write(bp, "Error in encoding\n", 18) <= 0)
|
||||
goto end;
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
hl = (p - op);
|
||||
length -= hl;
|
||||
/*
|
||||
* if j == 0x21 it is a constructed indefinite length object
|
||||
*/
|
||||
if (BIO_printf(bp, "%5ld:", (long)offset + (long)(op - *pp))
|
||||
<= 0)
|
||||
goto end;
|
||||
|
||||
if (j != (V_ASN1_CONSTRUCTED | 1))
|
||||
{
|
||||
if (BIO_printf(bp,"d=%-2d hl=%ld l=%4ld ",
|
||||
depth,(long)hl,len) <= 0)
|
||||
goto end;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BIO_printf(bp,"d=%-2d hl=%ld l=inf ",
|
||||
depth,(long)hl) <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (!asn1_print_info(bp,tag,xclass,j,(indent)?depth:0))
|
||||
goto end;
|
||||
if (j & V_ASN1_CONSTRUCTED)
|
||||
{
|
||||
ep=p+len;
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto end;
|
||||
if (len > length)
|
||||
{
|
||||
BIO_printf(bp,
|
||||
"length is greater than %ld\n",length);
|
||||
ret=0;
|
||||
goto end;
|
||||
}
|
||||
if ((j == 0x21) && (len == 0))
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
r=asn1_parse2(bp,&p,(long)(tot-p),
|
||||
offset+(p - *pp),depth+1,
|
||||
indent,dump);
|
||||
if (r == 0) { ret=0; goto end; }
|
||||
if ((r == 2) || (p >= tot)) break;
|
||||
}
|
||||
}
|
||||
else
|
||||
while (p < ep)
|
||||
{
|
||||
r=asn1_parse2(bp,&p,(long)len,
|
||||
offset+(p - *pp),depth+1,
|
||||
indent,dump);
|
||||
if (r == 0) { ret=0; goto end; }
|
||||
}
|
||||
}
|
||||
else if (xclass != 0)
|
||||
{
|
||||
p+=len;
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto end;
|
||||
}
|
||||
else
|
||||
{
|
||||
nl=0;
|
||||
if ( (tag == V_ASN1_PRINTABLESTRING) ||
|
||||
(tag == V_ASN1_T61STRING) ||
|
||||
(tag == V_ASN1_IA5STRING) ||
|
||||
(tag == V_ASN1_VISIBLESTRING) ||
|
||||
(tag == V_ASN1_NUMERICSTRING) ||
|
||||
(tag == V_ASN1_UTF8STRING) ||
|
||||
(tag == V_ASN1_UTCTIME) ||
|
||||
(tag == V_ASN1_GENERALIZEDTIME))
|
||||
{
|
||||
if (BIO_write(bp,":",1) <= 0) goto end;
|
||||
if ((len > 0) &&
|
||||
BIO_write(bp,(const char *)p,(int)len)
|
||||
!= (int)len)
|
||||
goto end;
|
||||
}
|
||||
else if (tag == V_ASN1_OBJECT)
|
||||
{
|
||||
opp=op;
|
||||
if (d2i_ASN1_OBJECT(&o,&opp,len+hl) != NULL)
|
||||
{
|
||||
if (BIO_write(bp,":",1) <= 0) goto end;
|
||||
i2a_ASN1_OBJECT(bp,o);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BIO_write(bp,":BAD OBJECT",11) <= 0)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else if (tag == V_ASN1_BOOLEAN)
|
||||
{
|
||||
int ii;
|
||||
if (j != (V_ASN1_CONSTRUCTED | 1)) {
|
||||
if (BIO_printf(bp, "d=%-2d hl=%ld l=%4ld ",
|
||||
depth, (long)hl, len) <= 0)
|
||||
goto end;
|
||||
} else {
|
||||
if (BIO_printf(bp, "d=%-2d hl=%ld l=inf ", depth, (long)hl) <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (!asn1_print_info(bp, tag, xclass, j, (indent) ? depth : 0))
|
||||
goto end;
|
||||
if (j & V_ASN1_CONSTRUCTED) {
|
||||
ep = p + len;
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto end;
|
||||
if (len > length) {
|
||||
BIO_printf(bp, "length is greater than %ld\n", length);
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
if ((j == 0x21) && (len == 0)) {
|
||||
for (;;) {
|
||||
r = asn1_parse2(bp, &p, (long)(tot - p),
|
||||
offset + (p - *pp), depth + 1,
|
||||
indent, dump);
|
||||
if (r == 0) {
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
if ((r == 2) || (p >= tot))
|
||||
break;
|
||||
}
|
||||
} else
|
||||
while (p < ep) {
|
||||
r = asn1_parse2(bp, &p, (long)len,
|
||||
offset + (p - *pp), depth + 1,
|
||||
indent, dump);
|
||||
if (r == 0) {
|
||||
ret = 0;
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
} else if (xclass != 0) {
|
||||
p += len;
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto end;
|
||||
} else {
|
||||
nl = 0;
|
||||
if ((tag == V_ASN1_PRINTABLESTRING) ||
|
||||
(tag == V_ASN1_T61STRING) ||
|
||||
(tag == V_ASN1_IA5STRING) ||
|
||||
(tag == V_ASN1_VISIBLESTRING) ||
|
||||
(tag == V_ASN1_NUMERICSTRING) ||
|
||||
(tag == V_ASN1_UTF8STRING) ||
|
||||
(tag == V_ASN1_UTCTIME) || (tag == V_ASN1_GENERALIZEDTIME)) {
|
||||
if (BIO_write(bp, ":", 1) <= 0)
|
||||
goto end;
|
||||
if ((len > 0) && BIO_write(bp, (const char *)p, (int)len)
|
||||
!= (int)len)
|
||||
goto end;
|
||||
} else if (tag == V_ASN1_OBJECT) {
|
||||
opp = op;
|
||||
if (d2i_ASN1_OBJECT(&o, &opp, len + hl) != NULL) {
|
||||
if (BIO_write(bp, ":", 1) <= 0)
|
||||
goto end;
|
||||
i2a_ASN1_OBJECT(bp, o);
|
||||
} else {
|
||||
if (BIO_write(bp, ":BAD OBJECT", 11) <= 0)
|
||||
goto end;
|
||||
}
|
||||
} else if (tag == V_ASN1_BOOLEAN) {
|
||||
int ii;
|
||||
|
||||
opp=op;
|
||||
ii=d2i_ASN1_BOOLEAN(NULL,&opp,len+hl);
|
||||
if (ii < 0)
|
||||
{
|
||||
if (BIO_write(bp,"Bad boolean\n",12) <= 0)
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bp,":%d",ii);
|
||||
}
|
||||
else if (tag == V_ASN1_BMPSTRING)
|
||||
{
|
||||
/* do the BMP thang */
|
||||
}
|
||||
else if (tag == V_ASN1_OCTET_STRING)
|
||||
{
|
||||
int i,printable=1;
|
||||
opp = op;
|
||||
ii = d2i_ASN1_BOOLEAN(NULL, &opp, len + hl);
|
||||
if (ii < 0) {
|
||||
if (BIO_write(bp, "Bad boolean\n", 12) <= 0)
|
||||
goto end;
|
||||
}
|
||||
BIO_printf(bp, ":%d", ii);
|
||||
} else if (tag == V_ASN1_BMPSTRING) {
|
||||
/* do the BMP thang */
|
||||
} else if (tag == V_ASN1_OCTET_STRING) {
|
||||
int i, printable = 1;
|
||||
|
||||
opp=op;
|
||||
os=d2i_ASN1_OCTET_STRING(NULL,&opp,len+hl);
|
||||
if (os != NULL && os->length > 0)
|
||||
{
|
||||
opp = os->data;
|
||||
/* testing whether the octet string is
|
||||
* printable */
|
||||
for (i=0; i<os->length; i++)
|
||||
{
|
||||
if (( (opp[i] < ' ') &&
|
||||
(opp[i] != '\n') &&
|
||||
(opp[i] != '\r') &&
|
||||
(opp[i] != '\t')) ||
|
||||
(opp[i] > '~'))
|
||||
{
|
||||
printable=0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (printable)
|
||||
/* printable string */
|
||||
{
|
||||
if (BIO_write(bp,":",1) <= 0)
|
||||
goto end;
|
||||
if (BIO_write(bp,(const char *)opp,
|
||||
os->length) <= 0)
|
||||
goto end;
|
||||
}
|
||||
else if (!dump)
|
||||
/* not printable => print octet string
|
||||
* as hex dump */
|
||||
{
|
||||
if (BIO_write(bp,"[HEX DUMP]:",11) <= 0)
|
||||
goto end;
|
||||
for (i=0; i<os->length; i++)
|
||||
{
|
||||
if (BIO_printf(bp,"%02X"
|
||||
, opp[i]) <= 0)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
/* print the normal dump */
|
||||
{
|
||||
if (!nl)
|
||||
{
|
||||
if (BIO_write(bp,"\n",1) <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (BIO_dump_indent(bp,
|
||||
(const char *)opp,
|
||||
((dump == -1 || dump >
|
||||
os->length)?os->length:dump),
|
||||
dump_indent) <= 0)
|
||||
goto end;
|
||||
nl=1;
|
||||
}
|
||||
}
|
||||
if (os != NULL)
|
||||
{
|
||||
M_ASN1_OCTET_STRING_free(os);
|
||||
os=NULL;
|
||||
}
|
||||
}
|
||||
else if (tag == V_ASN1_INTEGER)
|
||||
{
|
||||
ASN1_INTEGER *bs;
|
||||
int i;
|
||||
opp = op;
|
||||
os = d2i_ASN1_OCTET_STRING(NULL, &opp, len + hl);
|
||||
if (os != NULL && os->length > 0) {
|
||||
opp = os->data;
|
||||
/*
|
||||
* testing whether the octet string is printable
|
||||
*/
|
||||
for (i = 0; i < os->length; i++) {
|
||||
if (((opp[i] < ' ') &&
|
||||
(opp[i] != '\n') &&
|
||||
(opp[i] != '\r') &&
|
||||
(opp[i] != '\t')) || (opp[i] > '~')) {
|
||||
printable = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (printable)
|
||||
/* printable string */
|
||||
{
|
||||
if (BIO_write(bp, ":", 1) <= 0)
|
||||
goto end;
|
||||
if (BIO_write(bp, (const char *)opp, os->length) <= 0)
|
||||
goto end;
|
||||
} else if (!dump)
|
||||
/*
|
||||
* not printable => print octet string as hex dump
|
||||
*/
|
||||
{
|
||||
if (BIO_write(bp, "[HEX DUMP]:", 11) <= 0)
|
||||
goto end;
|
||||
for (i = 0; i < os->length; i++) {
|
||||
if (BIO_printf(bp, "%02X", opp[i]) <= 0)
|
||||
goto end;
|
||||
}
|
||||
} else
|
||||
/* print the normal dump */
|
||||
{
|
||||
if (!nl) {
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (BIO_dump_indent(bp,
|
||||
(const char *)opp,
|
||||
((dump == -1 || dump >
|
||||
os->
|
||||
length) ? os->length : dump),
|
||||
dump_indent) <= 0)
|
||||
goto end;
|
||||
nl = 1;
|
||||
}
|
||||
}
|
||||
if (os != NULL) {
|
||||
M_ASN1_OCTET_STRING_free(os);
|
||||
os = NULL;
|
||||
}
|
||||
} else if (tag == V_ASN1_INTEGER) {
|
||||
ASN1_INTEGER *bs;
|
||||
int i;
|
||||
|
||||
opp=op;
|
||||
bs=d2i_ASN1_INTEGER(NULL,&opp,len+hl);
|
||||
if (bs != NULL)
|
||||
{
|
||||
if (BIO_write(bp,":",1) <= 0) goto end;
|
||||
if (bs->type == V_ASN1_NEG_INTEGER)
|
||||
if (BIO_write(bp,"-",1) <= 0)
|
||||
goto end;
|
||||
for (i=0; i<bs->length; i++)
|
||||
{
|
||||
if (BIO_printf(bp,"%02X",
|
||||
bs->data[i]) <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (bs->length == 0)
|
||||
{
|
||||
if (BIO_write(bp,"00",2) <= 0)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BIO_write(bp,"BAD INTEGER",11) <= 0)
|
||||
goto end;
|
||||
}
|
||||
M_ASN1_INTEGER_free(bs);
|
||||
}
|
||||
else if (tag == V_ASN1_ENUMERATED)
|
||||
{
|
||||
ASN1_ENUMERATED *bs;
|
||||
int i;
|
||||
opp = op;
|
||||
bs = d2i_ASN1_INTEGER(NULL, &opp, len + hl);
|
||||
if (bs != NULL) {
|
||||
if (BIO_write(bp, ":", 1) <= 0)
|
||||
goto end;
|
||||
if (bs->type == V_ASN1_NEG_INTEGER)
|
||||
if (BIO_write(bp, "-", 1) <= 0)
|
||||
goto end;
|
||||
for (i = 0; i < bs->length; i++) {
|
||||
if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (bs->length == 0) {
|
||||
if (BIO_write(bp, "00", 2) <= 0)
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
if (BIO_write(bp, "BAD INTEGER", 11) <= 0)
|
||||
goto end;
|
||||
}
|
||||
M_ASN1_INTEGER_free(bs);
|
||||
} else if (tag == V_ASN1_ENUMERATED) {
|
||||
ASN1_ENUMERATED *bs;
|
||||
int i;
|
||||
|
||||
opp=op;
|
||||
bs=d2i_ASN1_ENUMERATED(NULL,&opp,len+hl);
|
||||
if (bs != NULL)
|
||||
{
|
||||
if (BIO_write(bp,":",1) <= 0) goto end;
|
||||
if (bs->type == V_ASN1_NEG_ENUMERATED)
|
||||
if (BIO_write(bp,"-",1) <= 0)
|
||||
goto end;
|
||||
for (i=0; i<bs->length; i++)
|
||||
{
|
||||
if (BIO_printf(bp,"%02X",
|
||||
bs->data[i]) <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (bs->length == 0)
|
||||
{
|
||||
if (BIO_write(bp,"00",2) <= 0)
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (BIO_write(bp,"BAD ENUMERATED",11) <= 0)
|
||||
goto end;
|
||||
}
|
||||
M_ASN1_ENUMERATED_free(bs);
|
||||
}
|
||||
else if (len > 0 && dump)
|
||||
{
|
||||
if (!nl)
|
||||
{
|
||||
if (BIO_write(bp,"\n",1) <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (BIO_dump_indent(bp,(const char *)p,
|
||||
((dump == -1 || dump > len)?len:dump),
|
||||
dump_indent) <= 0)
|
||||
goto end;
|
||||
nl=1;
|
||||
}
|
||||
opp = op;
|
||||
bs = d2i_ASN1_ENUMERATED(NULL, &opp, len + hl);
|
||||
if (bs != NULL) {
|
||||
if (BIO_write(bp, ":", 1) <= 0)
|
||||
goto end;
|
||||
if (bs->type == V_ASN1_NEG_ENUMERATED)
|
||||
if (BIO_write(bp, "-", 1) <= 0)
|
||||
goto end;
|
||||
for (i = 0; i < bs->length; i++) {
|
||||
if (BIO_printf(bp, "%02X", bs->data[i]) <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (bs->length == 0) {
|
||||
if (BIO_write(bp, "00", 2) <= 0)
|
||||
goto end;
|
||||
}
|
||||
} else {
|
||||
if (BIO_write(bp, "BAD ENUMERATED", 14) <= 0)
|
||||
goto end;
|
||||
}
|
||||
M_ASN1_ENUMERATED_free(bs);
|
||||
} else if (len > 0 && dump) {
|
||||
if (!nl) {
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto end;
|
||||
}
|
||||
if (BIO_dump_indent(bp, (const char *)p,
|
||||
((dump == -1 || dump > len) ? len : dump),
|
||||
dump_indent) <= 0)
|
||||
goto end;
|
||||
nl = 1;
|
||||
}
|
||||
|
||||
if (!nl)
|
||||
{
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto end;
|
||||
}
|
||||
p+=len;
|
||||
if ((tag == V_ASN1_EOC) && (xclass == 0))
|
||||
{
|
||||
ret=2; /* End of sequence */
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
length-=len;
|
||||
}
|
||||
ret=1;
|
||||
end:
|
||||
if (o != NULL) ASN1_OBJECT_free(o);
|
||||
if (os != NULL) M_ASN1_OCTET_STRING_free(os);
|
||||
*pp=p;
|
||||
return(ret);
|
||||
}
|
||||
if (!nl) {
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto end;
|
||||
}
|
||||
p += len;
|
||||
if ((tag == V_ASN1_EOC) && (xclass == 0)) {
|
||||
ret = 2; /* End of sequence */
|
||||
goto end;
|
||||
}
|
||||
}
|
||||
length -= len;
|
||||
}
|
||||
ret = 1;
|
||||
end:
|
||||
if (o != NULL)
|
||||
ASN1_OBJECT_free(o);
|
||||
if (os != NULL)
|
||||
M_ASN1_OCTET_STRING_free(os);
|
||||
*pp = p;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
const char *ASN1_tag2str(int tag)
|
||||
{
|
||||
static const char * const tag2str[] = {
|
||||
"EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING", /* 0-4 */
|
||||
"NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL", /* 5-9 */
|
||||
"ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>", /* 10-13 */
|
||||
"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET", /* 15-17 */
|
||||
"NUMERICSTRING", "PRINTABLESTRING", "T61STRING", /* 18-20 */
|
||||
"VIDEOTEXSTRING", "IA5STRING", "UTCTIME","GENERALIZEDTIME", /* 21-24 */
|
||||
"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING", /* 25-27 */
|
||||
"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING" /* 28-30 */
|
||||
};
|
||||
static const char *const tag2str[] = {
|
||||
/* 0-4 */
|
||||
"EOC", "BOOLEAN", "INTEGER", "BIT STRING", "OCTET STRING",
|
||||
/* 5-9 */
|
||||
"NULL", "OBJECT", "OBJECT DESCRIPTOR", "EXTERNAL", "REAL",
|
||||
/* 10-13 */
|
||||
"ENUMERATED", "<ASN1 11>", "UTF8STRING", "<ASN1 13>",
|
||||
/* 15-17 */
|
||||
"<ASN1 14>", "<ASN1 15>", "SEQUENCE", "SET",
|
||||
/* 18-20 */
|
||||
"NUMERICSTRING", "PRINTABLESTRING", "T61STRING",
|
||||
/* 21-24 */
|
||||
"VIDEOTEXSTRING", "IA5STRING", "UTCTIME", "GENERALIZEDTIME",
|
||||
/* 25-27 */
|
||||
"GRAPHICSTRING", "VISIBLESTRING", "GENERALSTRING",
|
||||
/* 28-30 */
|
||||
"UNIVERSALSTRING", "<ASN1 29>", "BMPSTRING"
|
||||
};
|
||||
|
||||
if((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
|
||||
tag &= ~0x100;
|
||||
if ((tag == V_ASN1_NEG_INTEGER) || (tag == V_ASN1_NEG_ENUMERATED))
|
||||
tag &= ~0x100;
|
||||
|
||||
if(tag < 0 || tag > 30) return "(unknown)";
|
||||
return tag2str[tag];
|
||||
if (tag < 0 || tag > 30)
|
||||
return "(unknown)";
|
||||
return tag2str[tag];
|
||||
}
|
||||
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
/* asn_moid.c */
|
||||
/* Written by Stephen Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2001.
|
||||
/*
|
||||
* Written by Stephen Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2001.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2001-2004 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -69,92 +70,84 @@
|
||||
static int do_create(char *value, char *name);
|
||||
|
||||
static int oid_module_init(CONF_IMODULE *md, const CONF *cnf)
|
||||
{
|
||||
int i;
|
||||
const char *oid_section;
|
||||
STACK_OF(CONF_VALUE) *sktmp;
|
||||
CONF_VALUE *oval;
|
||||
oid_section = CONF_imodule_get_value(md);
|
||||
if(!(sktmp = NCONF_get_section(cnf, oid_section)))
|
||||
{
|
||||
ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
|
||||
return 0;
|
||||
}
|
||||
for(i = 0; i < sk_CONF_VALUE_num(sktmp); i++)
|
||||
{
|
||||
oval = sk_CONF_VALUE_value(sktmp, i);
|
||||
if(!do_create(oval->value, oval->name))
|
||||
{
|
||||
ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
int i;
|
||||
const char *oid_section;
|
||||
STACK_OF(CONF_VALUE) *sktmp;
|
||||
CONF_VALUE *oval;
|
||||
oid_section = CONF_imodule_get_value(md);
|
||||
if (!(sktmp = NCONF_get_section(cnf, oid_section))) {
|
||||
ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ERROR_LOADING_SECTION);
|
||||
return 0;
|
||||
}
|
||||
for (i = 0; i < sk_CONF_VALUE_num(sktmp); i++) {
|
||||
oval = sk_CONF_VALUE_value(sktmp, i);
|
||||
if (!do_create(oval->value, oval->name)) {
|
||||
ASN1err(ASN1_F_OID_MODULE_INIT, ASN1_R_ADDING_OBJECT);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void oid_module_finish(CONF_IMODULE *md)
|
||||
{
|
||||
OBJ_cleanup();
|
||||
}
|
||||
{
|
||||
OBJ_cleanup();
|
||||
}
|
||||
|
||||
void ASN1_add_oid_module(void)
|
||||
{
|
||||
CONF_module_add("oid_section", oid_module_init, oid_module_finish);
|
||||
}
|
||||
{
|
||||
CONF_module_add("oid_section", oid_module_init, oid_module_finish);
|
||||
}
|
||||
|
||||
/* Create an OID based on a name value pair. Accept two formats.
|
||||
/*-
|
||||
* Create an OID based on a name value pair. Accept two formats.
|
||||
* shortname = 1.2.3.4
|
||||
* shortname = some long name, 1.2.3.4
|
||||
*/
|
||||
|
||||
|
||||
static int do_create(char *value, char *name)
|
||||
{
|
||||
int nid;
|
||||
ASN1_OBJECT *oid;
|
||||
char *ln, *ostr, *p, *lntmp;
|
||||
p = strrchr(value, ',');
|
||||
if (!p)
|
||||
{
|
||||
ln = name;
|
||||
ostr = value;
|
||||
}
|
||||
else
|
||||
{
|
||||
ln = NULL;
|
||||
ostr = p + 1;
|
||||
if (!*ostr)
|
||||
return 0;
|
||||
while(isspace((unsigned char)*ostr)) ostr++;
|
||||
}
|
||||
{
|
||||
int nid;
|
||||
ASN1_OBJECT *oid;
|
||||
char *ln, *ostr, *p, *lntmp;
|
||||
p = strrchr(value, ',');
|
||||
if (!p) {
|
||||
ln = name;
|
||||
ostr = value;
|
||||
} else {
|
||||
ln = NULL;
|
||||
ostr = p + 1;
|
||||
if (!*ostr)
|
||||
return 0;
|
||||
while (isspace((unsigned char)*ostr))
|
||||
ostr++;
|
||||
}
|
||||
|
||||
nid = OBJ_create(ostr, name, ln);
|
||||
nid = OBJ_create(ostr, name, ln);
|
||||
|
||||
if (nid == NID_undef)
|
||||
return 0;
|
||||
if (nid == NID_undef)
|
||||
return 0;
|
||||
|
||||
if (p)
|
||||
{
|
||||
ln = value;
|
||||
while(isspace((unsigned char)*ln)) ln++;
|
||||
p--;
|
||||
while(isspace((unsigned char)*p))
|
||||
{
|
||||
if (p == ln)
|
||||
return 0;
|
||||
p--;
|
||||
}
|
||||
p++;
|
||||
lntmp = OPENSSL_malloc((p - ln) + 1);
|
||||
if (lntmp == NULL)
|
||||
return 0;
|
||||
memcpy(lntmp, ln, p - ln);
|
||||
lntmp[p - ln] = 0;
|
||||
oid = OBJ_nid2obj(nid);
|
||||
oid->ln = lntmp;
|
||||
}
|
||||
if (p) {
|
||||
ln = value;
|
||||
while (isspace((unsigned char)*ln))
|
||||
ln++;
|
||||
p--;
|
||||
while (isspace((unsigned char)*p)) {
|
||||
if (p == ln)
|
||||
return 0;
|
||||
p--;
|
||||
}
|
||||
p++;
|
||||
lntmp = OPENSSL_malloc((p - ln) + 1);
|
||||
if (lntmp == NULL)
|
||||
return 0;
|
||||
memcpy(lntmp, ln, p - ln);
|
||||
lntmp[p - ln] = 0;
|
||||
oid = OBJ_nid2obj(nid);
|
||||
oid->ln = lntmp;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* asn_pack.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -67,82 +68,95 @@
|
||||
/* Turn an ASN1 encoded SEQUENCE OF into a STACK of structures */
|
||||
|
||||
STACK_OF(OPENSSL_BLOCK) *ASN1_seq_unpack(const unsigned char *buf, int len,
|
||||
d2i_of_void *d2i, void (*free_func)(OPENSSL_BLOCK))
|
||||
d2i_of_void *d2i,
|
||||
void (*free_func) (OPENSSL_BLOCK))
|
||||
{
|
||||
STACK_OF(OPENSSL_BLOCK) *sk;
|
||||
const unsigned char *pbuf;
|
||||
pbuf = buf;
|
||||
pbuf = buf;
|
||||
if (!(sk = d2i_ASN1_SET(NULL, &pbuf, len, d2i, free_func,
|
||||
V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL)))
|
||||
ASN1err(ASN1_F_ASN1_SEQ_UNPACK,ASN1_R_DECODE_ERROR);
|
||||
V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL)))
|
||||
ASN1err(ASN1_F_ASN1_SEQ_UNPACK, ASN1_R_DECODE_ERROR);
|
||||
return sk;
|
||||
}
|
||||
|
||||
/* Turn a STACK structures into an ASN1 encoded SEQUENCE OF structure in a
|
||||
/*
|
||||
* Turn a STACK structures into an ASN1 encoded SEQUENCE OF structure in a
|
||||
* OPENSSL_malloc'ed buffer
|
||||
*/
|
||||
|
||||
unsigned char *ASN1_seq_pack(STACK_OF(OPENSSL_BLOCK) *safes, i2d_of_void *i2d,
|
||||
unsigned char **buf, int *len)
|
||||
unsigned char **buf, int *len)
|
||||
{
|
||||
int safelen;
|
||||
unsigned char *safe, *p;
|
||||
if (!(safelen = i2d_ASN1_SET(safes, NULL, i2d, V_ASN1_SEQUENCE,
|
||||
V_ASN1_UNIVERSAL, IS_SEQUENCE))) {
|
||||
ASN1err(ASN1_F_ASN1_SEQ_PACK,ASN1_R_ENCODE_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
if (!(safe = OPENSSL_malloc (safelen))) {
|
||||
ASN1err(ASN1_F_ASN1_SEQ_PACK,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
p = safe;
|
||||
i2d_ASN1_SET(safes, &p, i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,
|
||||
IS_SEQUENCE);
|
||||
if (len) *len = safelen;
|
||||
if (buf) *buf = safe;
|
||||
return safe;
|
||||
int safelen;
|
||||
unsigned char *safe, *p;
|
||||
if (!(safelen = i2d_ASN1_SET(safes, NULL, i2d, V_ASN1_SEQUENCE,
|
||||
V_ASN1_UNIVERSAL, IS_SEQUENCE))) {
|
||||
ASN1err(ASN1_F_ASN1_SEQ_PACK, ASN1_R_ENCODE_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
if (!(safe = OPENSSL_malloc(safelen))) {
|
||||
ASN1err(ASN1_F_ASN1_SEQ_PACK, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
p = safe;
|
||||
i2d_ASN1_SET(safes, &p, i2d, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL,
|
||||
IS_SEQUENCE);
|
||||
if (len)
|
||||
*len = safelen;
|
||||
if (buf)
|
||||
*buf = safe;
|
||||
return safe;
|
||||
}
|
||||
|
||||
/* Extract an ASN1 object from an ASN1_STRING */
|
||||
|
||||
void *ASN1_unpack_string(ASN1_STRING *oct, d2i_of_void *d2i)
|
||||
{
|
||||
const unsigned char *p;
|
||||
char *ret;
|
||||
const unsigned char *p;
|
||||
char *ret;
|
||||
|
||||
p = oct->data;
|
||||
if(!(ret = d2i(NULL, &p, oct->length)))
|
||||
ASN1err(ASN1_F_ASN1_UNPACK_STRING,ASN1_R_DECODE_ERROR);
|
||||
return ret;
|
||||
p = oct->data;
|
||||
if (!(ret = d2i(NULL, &p, oct->length)))
|
||||
ASN1err(ASN1_F_ASN1_UNPACK_STRING, ASN1_R_DECODE_ERROR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Pack an ASN1 object into an ASN1_STRING */
|
||||
|
||||
ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct)
|
||||
{
|
||||
unsigned char *p;
|
||||
ASN1_STRING *octmp;
|
||||
unsigned char *p;
|
||||
ASN1_STRING *octmp;
|
||||
|
||||
if (!oct || !*oct) {
|
||||
if (!(octmp = ASN1_STRING_new ())) {
|
||||
ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (oct) *oct = octmp;
|
||||
} else octmp = *oct;
|
||||
|
||||
if (!(octmp->length = i2d(obj, NULL))) {
|
||||
ASN1err(ASN1_F_ASN1_PACK_STRING,ASN1_R_ENCODE_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
if (!(p = OPENSSL_malloc (octmp->length))) {
|
||||
ASN1err(ASN1_F_ASN1_PACK_STRING,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
octmp->data = p;
|
||||
i2d (obj, &p);
|
||||
return octmp;
|
||||
if (!oct || !*oct) {
|
||||
if (!(octmp = ASN1_STRING_new())) {
|
||||
ASN1err(ASN1_F_ASN1_PACK_STRING, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (oct)
|
||||
*oct = octmp;
|
||||
} else
|
||||
octmp = *oct;
|
||||
|
||||
if (!(octmp->length = i2d(obj, NULL))) {
|
||||
ASN1err(ASN1_F_ASN1_PACK_STRING, ASN1_R_ENCODE_ERROR);
|
||||
goto err;
|
||||
}
|
||||
if (!(p = OPENSSL_malloc(octmp->length))) {
|
||||
ASN1err(ASN1_F_ASN1_PACK_STRING, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
octmp->data = p;
|
||||
i2d(obj, &p);
|
||||
return octmp;
|
||||
err:
|
||||
if (!oct || !*oct) {
|
||||
ASN1_STRING_free(octmp);
|
||||
if (oct)
|
||||
*oct = NULL;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
@ -151,41 +165,43 @@ ASN1_STRING *ASN1_pack_string(void *obj, i2d_of_void *i2d, ASN1_STRING **oct)
|
||||
|
||||
ASN1_STRING *ASN1_item_pack(void *obj, const ASN1_ITEM *it, ASN1_STRING **oct)
|
||||
{
|
||||
ASN1_STRING *octmp;
|
||||
ASN1_STRING *octmp;
|
||||
|
||||
if (!oct || !*oct) {
|
||||
if (!(octmp = ASN1_STRING_new ())) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_PACK,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (oct) *oct = octmp;
|
||||
} else octmp = *oct;
|
||||
if (!oct || !*oct) {
|
||||
if (!(octmp = ASN1_STRING_new())) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
if (oct)
|
||||
*oct = octmp;
|
||||
} else
|
||||
octmp = *oct;
|
||||
|
||||
if(octmp->data) {
|
||||
OPENSSL_free(octmp->data);
|
||||
octmp->data = NULL;
|
||||
}
|
||||
|
||||
if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_PACK,ASN1_R_ENCODE_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
if (!octmp->data) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_PACK,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
return octmp;
|
||||
if (octmp->data) {
|
||||
OPENSSL_free(octmp->data);
|
||||
octmp->data = NULL;
|
||||
}
|
||||
|
||||
if (!(octmp->length = ASN1_item_i2d(obj, &octmp->data, it))) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_PACK, ASN1_R_ENCODE_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
if (!octmp->data) {
|
||||
ASN1err(ASN1_F_ASN1_ITEM_PACK, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
return octmp;
|
||||
}
|
||||
|
||||
/* Extract an ASN1 object from an ASN1_STRING */
|
||||
|
||||
void *ASN1_item_unpack(ASN1_STRING *oct, const ASN1_ITEM *it)
|
||||
{
|
||||
const unsigned char *p;
|
||||
void *ret;
|
||||
const unsigned char *p;
|
||||
void *ret;
|
||||
|
||||
p = oct->data;
|
||||
if(!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
|
||||
ASN1err(ASN1_F_ASN1_ITEM_UNPACK,ASN1_R_DECODE_ERROR);
|
||||
return ret;
|
||||
p = oct->data;
|
||||
if (!(ret = ASN1_item_d2i(NULL, &p, oct->length, it)))
|
||||
ASN1err(ASN1_F_ASN1_ITEM_UNPACK, ASN1_R_DECODE_ERROR);
|
||||
return ret;
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/* bio_asn1.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -56,9 +57,10 @@
|
||||
*
|
||||
*/
|
||||
|
||||
/* Experimental ASN1 BIO. When written through the data is converted
|
||||
* to an ASN1 string type: default is OCTET STRING. Additional functions
|
||||
* can be provided to add prefix and suffix data.
|
||||
/*
|
||||
* Experimental ASN1 BIO. When written through the data is converted to an
|
||||
* ASN1 string type: default is OCTET STRING. Additional functions can be
|
||||
* provided to add prefix and suffix data.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
@ -68,49 +70,45 @@
|
||||
/* Must be large enough for biggest tag+length */
|
||||
#define DEFAULT_ASN1_BUF_SIZE 20
|
||||
|
||||
typedef enum
|
||||
{
|
||||
ASN1_STATE_START,
|
||||
ASN1_STATE_PRE_COPY,
|
||||
ASN1_STATE_HEADER,
|
||||
ASN1_STATE_HEADER_COPY,
|
||||
ASN1_STATE_DATA_COPY,
|
||||
ASN1_STATE_POST_COPY,
|
||||
ASN1_STATE_DONE
|
||||
} asn1_bio_state_t;
|
||||
typedef enum {
|
||||
ASN1_STATE_START,
|
||||
ASN1_STATE_PRE_COPY,
|
||||
ASN1_STATE_HEADER,
|
||||
ASN1_STATE_HEADER_COPY,
|
||||
ASN1_STATE_DATA_COPY,
|
||||
ASN1_STATE_POST_COPY,
|
||||
ASN1_STATE_DONE
|
||||
} asn1_bio_state_t;
|
||||
|
||||
typedef struct BIO_ASN1_EX_FUNCS_st
|
||||
{
|
||||
asn1_ps_func *ex_func;
|
||||
asn1_ps_func *ex_free_func;
|
||||
} BIO_ASN1_EX_FUNCS;
|
||||
typedef struct BIO_ASN1_EX_FUNCS_st {
|
||||
asn1_ps_func *ex_func;
|
||||
asn1_ps_func *ex_free_func;
|
||||
} BIO_ASN1_EX_FUNCS;
|
||||
|
||||
typedef struct BIO_ASN1_BUF_CTX_t
|
||||
{
|
||||
/* Internal state */
|
||||
asn1_bio_state_t state;
|
||||
/* Internal buffer */
|
||||
unsigned char *buf;
|
||||
/* Size of buffer */
|
||||
int bufsize;
|
||||
/* Current position in buffer */
|
||||
int bufpos;
|
||||
/* Current buffer length */
|
||||
int buflen;
|
||||
/* Amount of data to copy */
|
||||
int copylen;
|
||||
/* Class and tag to use */
|
||||
int asn1_class, asn1_tag;
|
||||
asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
|
||||
/* Extra buffer for prefix and suffix data */
|
||||
unsigned char *ex_buf;
|
||||
int ex_len;
|
||||
int ex_pos;
|
||||
void *ex_arg;
|
||||
} BIO_ASN1_BUF_CTX;
|
||||
typedef struct BIO_ASN1_BUF_CTX_t {
|
||||
/* Internal state */
|
||||
asn1_bio_state_t state;
|
||||
/* Internal buffer */
|
||||
unsigned char *buf;
|
||||
/* Size of buffer */
|
||||
int bufsize;
|
||||
/* Current position in buffer */
|
||||
int bufpos;
|
||||
/* Current buffer length */
|
||||
int buflen;
|
||||
/* Amount of data to copy */
|
||||
int copylen;
|
||||
/* Class and tag to use */
|
||||
int asn1_class, asn1_tag;
|
||||
asn1_ps_func *prefix, *prefix_free, *suffix, *suffix_free;
|
||||
/* Extra buffer for prefix and suffix data */
|
||||
unsigned char *ex_buf;
|
||||
int ex_len;
|
||||
int ex_pos;
|
||||
void *ex_arg;
|
||||
} BIO_ASN1_BUF_CTX;
|
||||
|
||||
|
||||
static int asn1_bio_write(BIO *h, const char *buf,int num);
|
||||
static int asn1_bio_write(BIO *h, const char *buf, int num);
|
||||
static int asn1_bio_read(BIO *h, char *buf, int size);
|
||||
static int asn1_bio_puts(BIO *h, const char *str);
|
||||
static int asn1_bio_gets(BIO *h, char *str, int size);
|
||||
@ -121,375 +119,364 @@ static long asn1_bio_callback_ctrl(BIO *h, int cmd, bio_info_cb *fp);
|
||||
|
||||
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size);
|
||||
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
|
||||
asn1_ps_func *cleanup, asn1_bio_state_t next);
|
||||
asn1_ps_func *cleanup, asn1_bio_state_t next);
|
||||
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
|
||||
asn1_ps_func *setup,
|
||||
asn1_bio_state_t ex_state,
|
||||
asn1_bio_state_t other_state);
|
||||
asn1_ps_func *setup,
|
||||
asn1_bio_state_t ex_state,
|
||||
asn1_bio_state_t other_state);
|
||||
|
||||
static BIO_METHOD methods_asn1=
|
||||
{
|
||||
BIO_TYPE_ASN1,
|
||||
"asn1",
|
||||
asn1_bio_write,
|
||||
asn1_bio_read,
|
||||
asn1_bio_puts,
|
||||
asn1_bio_gets,
|
||||
asn1_bio_ctrl,
|
||||
asn1_bio_new,
|
||||
asn1_bio_free,
|
||||
asn1_bio_callback_ctrl,
|
||||
};
|
||||
static BIO_METHOD methods_asn1 = {
|
||||
BIO_TYPE_ASN1,
|
||||
"asn1",
|
||||
asn1_bio_write,
|
||||
asn1_bio_read,
|
||||
asn1_bio_puts,
|
||||
asn1_bio_gets,
|
||||
asn1_bio_ctrl,
|
||||
asn1_bio_new,
|
||||
asn1_bio_free,
|
||||
asn1_bio_callback_ctrl,
|
||||
};
|
||||
|
||||
BIO_METHOD *BIO_f_asn1(void)
|
||||
{
|
||||
return(&methods_asn1);
|
||||
}
|
||||
|
||||
{
|
||||
return (&methods_asn1);
|
||||
}
|
||||
|
||||
static int asn1_bio_new(BIO *b)
|
||||
{
|
||||
BIO_ASN1_BUF_CTX *ctx;
|
||||
ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
|
||||
if (!ctx)
|
||||
return 0;
|
||||
if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE))
|
||||
return 0;
|
||||
b->init = 1;
|
||||
b->ptr = (char *)ctx;
|
||||
b->flags = 0;
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
BIO_ASN1_BUF_CTX *ctx;
|
||||
ctx = OPENSSL_malloc(sizeof(BIO_ASN1_BUF_CTX));
|
||||
if (!ctx)
|
||||
return 0;
|
||||
if (!asn1_bio_init(ctx, DEFAULT_ASN1_BUF_SIZE)) {
|
||||
OPENSSL_free(ctx);
|
||||
return 0;
|
||||
}
|
||||
b->init = 1;
|
||||
b->ptr = (char *)ctx;
|
||||
b->flags = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int asn1_bio_init(BIO_ASN1_BUF_CTX *ctx, int size)
|
||||
{
|
||||
ctx->buf = OPENSSL_malloc(size);
|
||||
if (!ctx->buf)
|
||||
return 0;
|
||||
ctx->bufsize = size;
|
||||
ctx->bufpos = 0;
|
||||
ctx->buflen = 0;
|
||||
ctx->copylen = 0;
|
||||
ctx->asn1_class = V_ASN1_UNIVERSAL;
|
||||
ctx->asn1_tag = V_ASN1_OCTET_STRING;
|
||||
ctx->ex_buf = 0;
|
||||
ctx->ex_pos = 0;
|
||||
ctx->ex_len = 0;
|
||||
ctx->state = ASN1_STATE_START;
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
ctx->buf = OPENSSL_malloc(size);
|
||||
if (!ctx->buf)
|
||||
return 0;
|
||||
ctx->bufsize = size;
|
||||
ctx->bufpos = 0;
|
||||
ctx->buflen = 0;
|
||||
ctx->copylen = 0;
|
||||
ctx->asn1_class = V_ASN1_UNIVERSAL;
|
||||
ctx->asn1_tag = V_ASN1_OCTET_STRING;
|
||||
ctx->ex_buf = 0;
|
||||
ctx->ex_pos = 0;
|
||||
ctx->ex_len = 0;
|
||||
ctx->state = ASN1_STATE_START;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int asn1_bio_free(BIO *b)
|
||||
{
|
||||
BIO_ASN1_BUF_CTX *ctx;
|
||||
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
if (ctx->buf)
|
||||
OPENSSL_free(ctx->buf);
|
||||
OPENSSL_free(ctx);
|
||||
b->init = 0;
|
||||
b->ptr = NULL;
|
||||
b->flags = 0;
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
BIO_ASN1_BUF_CTX *ctx;
|
||||
ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
if (ctx->buf)
|
||||
OPENSSL_free(ctx->buf);
|
||||
OPENSSL_free(ctx);
|
||||
b->init = 0;
|
||||
b->ptr = NULL;
|
||||
b->flags = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int asn1_bio_write(BIO *b, const char *in , int inl)
|
||||
{
|
||||
BIO_ASN1_BUF_CTX *ctx;
|
||||
int wrmax, wrlen, ret;
|
||||
unsigned char *p;
|
||||
if (!in || (inl < 0) || (b->next_bio == NULL))
|
||||
return 0;
|
||||
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
static int asn1_bio_write(BIO *b, const char *in, int inl)
|
||||
{
|
||||
BIO_ASN1_BUF_CTX *ctx;
|
||||
int wrmax, wrlen, ret;
|
||||
unsigned char *p;
|
||||
if (!in || (inl < 0) || (b->next_bio == NULL))
|
||||
return 0;
|
||||
ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
|
||||
wrlen = 0;
|
||||
ret = -1;
|
||||
wrlen = 0;
|
||||
ret = -1;
|
||||
|
||||
for(;;)
|
||||
{
|
||||
switch (ctx->state)
|
||||
{
|
||||
for (;;) {
|
||||
switch (ctx->state) {
|
||||
|
||||
/* Setup prefix data, call it */
|
||||
case ASN1_STATE_START:
|
||||
if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
|
||||
ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
|
||||
return 0;
|
||||
break;
|
||||
/* Setup prefix data, call it */
|
||||
case ASN1_STATE_START:
|
||||
if (!asn1_bio_setup_ex(b, ctx, ctx->prefix,
|
||||
ASN1_STATE_PRE_COPY, ASN1_STATE_HEADER))
|
||||
return 0;
|
||||
break;
|
||||
|
||||
/* Copy any pre data first */
|
||||
case ASN1_STATE_PRE_COPY:
|
||||
/* Copy any pre data first */
|
||||
case ASN1_STATE_PRE_COPY:
|
||||
|
||||
ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
|
||||
ASN1_STATE_HEADER);
|
||||
ret = asn1_bio_flush_ex(b, ctx, ctx->prefix_free,
|
||||
ASN1_STATE_HEADER);
|
||||
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case ASN1_STATE_HEADER:
|
||||
ctx->buflen =
|
||||
ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
|
||||
OPENSSL_assert(ctx->buflen <= ctx->bufsize);
|
||||
p = ctx->buf;
|
||||
ASN1_put_object(&p, 0, inl,
|
||||
ctx->asn1_tag, ctx->asn1_class);
|
||||
ctx->copylen = inl;
|
||||
ctx->state = ASN1_STATE_HEADER_COPY;
|
||||
case ASN1_STATE_HEADER:
|
||||
ctx->buflen = ASN1_object_size(0, inl, ctx->asn1_tag) - inl;
|
||||
OPENSSL_assert(ctx->buflen <= ctx->bufsize);
|
||||
p = ctx->buf;
|
||||
ASN1_put_object(&p, 0, inl, ctx->asn1_tag, ctx->asn1_class);
|
||||
ctx->copylen = inl;
|
||||
ctx->state = ASN1_STATE_HEADER_COPY;
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case ASN1_STATE_HEADER_COPY:
|
||||
ret = BIO_write(b->next_bio,
|
||||
ctx->buf + ctx->bufpos, ctx->buflen);
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
case ASN1_STATE_HEADER_COPY:
|
||||
ret = BIO_write(b->next_bio, ctx->buf + ctx->bufpos, ctx->buflen);
|
||||
if (ret <= 0)
|
||||
goto done;
|
||||
|
||||
ctx->buflen -= ret;
|
||||
if (ctx->buflen)
|
||||
ctx->bufpos += ret;
|
||||
else
|
||||
{
|
||||
ctx->bufpos = 0;
|
||||
ctx->state = ASN1_STATE_DATA_COPY;
|
||||
}
|
||||
ctx->buflen -= ret;
|
||||
if (ctx->buflen)
|
||||
ctx->bufpos += ret;
|
||||
else {
|
||||
ctx->bufpos = 0;
|
||||
ctx->state = ASN1_STATE_DATA_COPY;
|
||||
}
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
case ASN1_STATE_DATA_COPY:
|
||||
case ASN1_STATE_DATA_COPY:
|
||||
|
||||
if (inl > ctx->copylen)
|
||||
wrmax = ctx->copylen;
|
||||
else
|
||||
wrmax = inl;
|
||||
ret = BIO_write(b->next_bio, in, wrmax);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
wrlen += ret;
|
||||
ctx->copylen -= ret;
|
||||
in += ret;
|
||||
inl -= ret;
|
||||
if (inl > ctx->copylen)
|
||||
wrmax = ctx->copylen;
|
||||
else
|
||||
wrmax = inl;
|
||||
ret = BIO_write(b->next_bio, in, wrmax);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
wrlen += ret;
|
||||
ctx->copylen -= ret;
|
||||
in += ret;
|
||||
inl -= ret;
|
||||
|
||||
if (ctx->copylen == 0)
|
||||
ctx->state = ASN1_STATE_HEADER;
|
||||
if (ctx->copylen == 0)
|
||||
ctx->state = ASN1_STATE_HEADER;
|
||||
|
||||
if (inl == 0)
|
||||
goto done;
|
||||
if (inl == 0)
|
||||
goto done;
|
||||
|
||||
break;
|
||||
break;
|
||||
|
||||
default:
|
||||
BIO_clear_retry_flags(b);
|
||||
return 0;
|
||||
default:
|
||||
BIO_clear_retry_flags(b);
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
done:
|
||||
BIO_clear_retry_flags(b);
|
||||
BIO_copy_next_retry(b);
|
||||
done:
|
||||
BIO_clear_retry_flags(b);
|
||||
BIO_copy_next_retry(b);
|
||||
|
||||
return (wrlen > 0) ? wrlen : ret;
|
||||
return (wrlen > 0) ? wrlen : ret;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int asn1_bio_flush_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
|
||||
asn1_ps_func *cleanup, asn1_bio_state_t next)
|
||||
{
|
||||
int ret;
|
||||
if (ctx->ex_len <= 0)
|
||||
return 1;
|
||||
for(;;)
|
||||
{
|
||||
ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos,
|
||||
ctx->ex_len);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
ctx->ex_len -= ret;
|
||||
if (ctx->ex_len > 0)
|
||||
ctx->ex_pos += ret;
|
||||
else
|
||||
{
|
||||
if(cleanup)
|
||||
cleanup(b, &ctx->ex_buf, &ctx->ex_len,
|
||||
&ctx->ex_arg);
|
||||
ctx->state = next;
|
||||
ctx->ex_pos = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
asn1_ps_func *cleanup, asn1_bio_state_t next)
|
||||
{
|
||||
int ret;
|
||||
if (ctx->ex_len <= 0)
|
||||
return 1;
|
||||
for (;;) {
|
||||
ret = BIO_write(b->next_bio, ctx->ex_buf + ctx->ex_pos, ctx->ex_len);
|
||||
if (ret <= 0)
|
||||
break;
|
||||
ctx->ex_len -= ret;
|
||||
if (ctx->ex_len > 0)
|
||||
ctx->ex_pos += ret;
|
||||
else {
|
||||
if (cleanup)
|
||||
cleanup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg);
|
||||
ctx->state = next;
|
||||
ctx->ex_pos = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int asn1_bio_setup_ex(BIO *b, BIO_ASN1_BUF_CTX *ctx,
|
||||
asn1_ps_func *setup,
|
||||
asn1_bio_state_t ex_state,
|
||||
asn1_bio_state_t other_state)
|
||||
{
|
||||
if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg))
|
||||
{
|
||||
BIO_clear_retry_flags(b);
|
||||
return 0;
|
||||
}
|
||||
if (ctx->ex_len > 0)
|
||||
ctx->state = ex_state;
|
||||
else
|
||||
ctx->state = other_state;
|
||||
return 1;
|
||||
}
|
||||
asn1_ps_func *setup,
|
||||
asn1_bio_state_t ex_state,
|
||||
asn1_bio_state_t other_state)
|
||||
{
|
||||
if (setup && !setup(b, &ctx->ex_buf, &ctx->ex_len, &ctx->ex_arg)) {
|
||||
BIO_clear_retry_flags(b);
|
||||
return 0;
|
||||
}
|
||||
if (ctx->ex_len > 0)
|
||||
ctx->state = ex_state;
|
||||
else
|
||||
ctx->state = other_state;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int asn1_bio_read(BIO *b, char *in , int inl)
|
||||
{
|
||||
if (!b->next_bio)
|
||||
return 0;
|
||||
return BIO_read(b->next_bio, in , inl);
|
||||
}
|
||||
static int asn1_bio_read(BIO *b, char *in, int inl)
|
||||
{
|
||||
if (!b->next_bio)
|
||||
return 0;
|
||||
return BIO_read(b->next_bio, in, inl);
|
||||
}
|
||||
|
||||
static int asn1_bio_puts(BIO *b, const char *str)
|
||||
{
|
||||
return asn1_bio_write(b, str, strlen(str));
|
||||
}
|
||||
{
|
||||
return asn1_bio_write(b, str, strlen(str));
|
||||
}
|
||||
|
||||
static int asn1_bio_gets(BIO *b, char *str, int size)
|
||||
{
|
||||
if (!b->next_bio)
|
||||
return 0;
|
||||
return BIO_gets(b->next_bio, str , size);
|
||||
}
|
||||
{
|
||||
if (!b->next_bio)
|
||||
return 0;
|
||||
return BIO_gets(b->next_bio, str, size);
|
||||
}
|
||||
|
||||
static long asn1_bio_callback_ctrl(BIO *b, int cmd, bio_info_cb *fp)
|
||||
{
|
||||
if (b->next_bio == NULL) return(0);
|
||||
return BIO_callback_ctrl(b->next_bio,cmd,fp);
|
||||
}
|
||||
{
|
||||
if (b->next_bio == NULL)
|
||||
return (0);
|
||||
return BIO_callback_ctrl(b->next_bio, cmd, fp);
|
||||
}
|
||||
|
||||
static long asn1_bio_ctrl(BIO *b, int cmd, long arg1, void *arg2)
|
||||
{
|
||||
BIO_ASN1_BUF_CTX *ctx;
|
||||
BIO_ASN1_EX_FUNCS *ex_func;
|
||||
long ret = 1;
|
||||
ctx = (BIO_ASN1_BUF_CTX *) b->ptr;
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
switch(cmd)
|
||||
{
|
||||
{
|
||||
BIO_ASN1_BUF_CTX *ctx;
|
||||
BIO_ASN1_EX_FUNCS *ex_func;
|
||||
long ret = 1;
|
||||
ctx = (BIO_ASN1_BUF_CTX *)b->ptr;
|
||||
if (ctx == NULL)
|
||||
return 0;
|
||||
switch (cmd) {
|
||||
|
||||
case BIO_C_SET_PREFIX:
|
||||
ex_func = arg2;
|
||||
ctx->prefix = ex_func->ex_func;
|
||||
ctx->prefix_free = ex_func->ex_free_func;
|
||||
break;
|
||||
case BIO_C_SET_PREFIX:
|
||||
ex_func = arg2;
|
||||
ctx->prefix = ex_func->ex_func;
|
||||
ctx->prefix_free = ex_func->ex_free_func;
|
||||
break;
|
||||
|
||||
case BIO_C_GET_PREFIX:
|
||||
ex_func = arg2;
|
||||
ex_func->ex_func = ctx->prefix;
|
||||
ex_func->ex_free_func = ctx->prefix_free;
|
||||
break;
|
||||
case BIO_C_GET_PREFIX:
|
||||
ex_func = arg2;
|
||||
ex_func->ex_func = ctx->prefix;
|
||||
ex_func->ex_free_func = ctx->prefix_free;
|
||||
break;
|
||||
|
||||
case BIO_C_SET_SUFFIX:
|
||||
ex_func = arg2;
|
||||
ctx->suffix = ex_func->ex_func;
|
||||
ctx->suffix_free = ex_func->ex_free_func;
|
||||
break;
|
||||
case BIO_C_SET_SUFFIX:
|
||||
ex_func = arg2;
|
||||
ctx->suffix = ex_func->ex_func;
|
||||
ctx->suffix_free = ex_func->ex_free_func;
|
||||
break;
|
||||
|
||||
case BIO_C_GET_SUFFIX:
|
||||
ex_func = arg2;
|
||||
ex_func->ex_func = ctx->suffix;
|
||||
ex_func->ex_free_func = ctx->suffix_free;
|
||||
break;
|
||||
case BIO_C_GET_SUFFIX:
|
||||
ex_func = arg2;
|
||||
ex_func->ex_func = ctx->suffix;
|
||||
ex_func->ex_free_func = ctx->suffix_free;
|
||||
break;
|
||||
|
||||
case BIO_C_SET_EX_ARG:
|
||||
ctx->ex_arg = arg2;
|
||||
break;
|
||||
case BIO_C_SET_EX_ARG:
|
||||
ctx->ex_arg = arg2;
|
||||
break;
|
||||
|
||||
case BIO_C_GET_EX_ARG:
|
||||
*(void **)arg2 = ctx->ex_arg;
|
||||
break;
|
||||
case BIO_C_GET_EX_ARG:
|
||||
*(void **)arg2 = ctx->ex_arg;
|
||||
break;
|
||||
|
||||
case BIO_CTRL_FLUSH:
|
||||
if (!b->next_bio)
|
||||
return 0;
|
||||
case BIO_CTRL_FLUSH:
|
||||
if (!b->next_bio)
|
||||
return 0;
|
||||
|
||||
/* Call post function if possible */
|
||||
if (ctx->state == ASN1_STATE_HEADER)
|
||||
{
|
||||
if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
|
||||
ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
|
||||
return 0;
|
||||
}
|
||||
/* Call post function if possible */
|
||||
if (ctx->state == ASN1_STATE_HEADER) {
|
||||
if (!asn1_bio_setup_ex(b, ctx, ctx->suffix,
|
||||
ASN1_STATE_POST_COPY, ASN1_STATE_DONE))
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (ctx->state == ASN1_STATE_POST_COPY)
|
||||
{
|
||||
ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
|
||||
ASN1_STATE_DONE);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
}
|
||||
if (ctx->state == ASN1_STATE_POST_COPY) {
|
||||
ret = asn1_bio_flush_ex(b, ctx, ctx->suffix_free,
|
||||
ASN1_STATE_DONE);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (ctx->state == ASN1_STATE_DONE)
|
||||
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
|
||||
else
|
||||
{
|
||||
BIO_clear_retry_flags(b);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
if (ctx->state == ASN1_STATE_DONE)
|
||||
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
|
||||
else {
|
||||
BIO_clear_retry_flags(b);
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
if (!b->next_bio)
|
||||
return 0;
|
||||
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
|
||||
|
||||
default:
|
||||
if (!b->next_bio)
|
||||
return 0;
|
||||
return BIO_ctrl(b->next_bio, cmd, arg1, arg2);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static int asn1_bio_set_ex(BIO *b, int cmd,
|
||||
asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
|
||||
{
|
||||
BIO_ASN1_EX_FUNCS extmp;
|
||||
extmp.ex_func = ex_func;
|
||||
extmp.ex_free_func = ex_free_func;
|
||||
return BIO_ctrl(b, cmd, 0, &extmp);
|
||||
}
|
||||
asn1_ps_func *ex_func, asn1_ps_func *ex_free_func)
|
||||
{
|
||||
BIO_ASN1_EX_FUNCS extmp;
|
||||
extmp.ex_func = ex_func;
|
||||
extmp.ex_free_func = ex_free_func;
|
||||
return BIO_ctrl(b, cmd, 0, &extmp);
|
||||
}
|
||||
|
||||
static int asn1_bio_get_ex(BIO *b, int cmd,
|
||||
asn1_ps_func **ex_func, asn1_ps_func **ex_free_func)
|
||||
{
|
||||
BIO_ASN1_EX_FUNCS extmp;
|
||||
int ret;
|
||||
ret = BIO_ctrl(b, cmd, 0, &extmp);
|
||||
if (ret > 0)
|
||||
{
|
||||
*ex_func = extmp.ex_func;
|
||||
*ex_free_func = extmp.ex_free_func;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
asn1_ps_func **ex_func,
|
||||
asn1_ps_func **ex_free_func)
|
||||
{
|
||||
BIO_ASN1_EX_FUNCS extmp;
|
||||
int ret;
|
||||
ret = BIO_ctrl(b, cmd, 0, &extmp);
|
||||
if (ret > 0) {
|
||||
*ex_func = extmp.ex_func;
|
||||
*ex_free_func = extmp.ex_free_func;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix, asn1_ps_func *prefix_free)
|
||||
{
|
||||
return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
|
||||
}
|
||||
int BIO_asn1_set_prefix(BIO *b, asn1_ps_func *prefix,
|
||||
asn1_ps_func *prefix_free)
|
||||
{
|
||||
return asn1_bio_set_ex(b, BIO_C_SET_PREFIX, prefix, prefix_free);
|
||||
}
|
||||
|
||||
int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix, asn1_ps_func **pprefix_free)
|
||||
{
|
||||
return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
|
||||
}
|
||||
int BIO_asn1_get_prefix(BIO *b, asn1_ps_func **pprefix,
|
||||
asn1_ps_func **pprefix_free)
|
||||
{
|
||||
return asn1_bio_get_ex(b, BIO_C_GET_PREFIX, pprefix, pprefix_free);
|
||||
}
|
||||
|
||||
int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix, asn1_ps_func *suffix_free)
|
||||
{
|
||||
return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
|
||||
}
|
||||
int BIO_asn1_set_suffix(BIO *b, asn1_ps_func *suffix,
|
||||
asn1_ps_func *suffix_free)
|
||||
{
|
||||
return asn1_bio_set_ex(b, BIO_C_SET_SUFFIX, suffix, suffix_free);
|
||||
}
|
||||
|
||||
int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix, asn1_ps_func **psuffix_free)
|
||||
{
|
||||
return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
|
||||
}
|
||||
int BIO_asn1_get_suffix(BIO *b, asn1_ps_func **psuffix,
|
||||
asn1_ps_func **psuffix_free)
|
||||
{
|
||||
return asn1_bio_get_ex(b, BIO_C_GET_SUFFIX, psuffix, psuffix_free);
|
||||
}
|
||||
|
||||
@ -1,5 +1,6 @@
|
||||
/* bio_ndef.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project.
|
||||
*/
|
||||
/* ====================================================================
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -61,183 +62,187 @@
|
||||
|
||||
/* Experimental NDEF ASN1 BIO support routines */
|
||||
|
||||
/* The usage is quite simple, initialize an ASN1 structure,
|
||||
* get a BIO from it then any data written through the BIO
|
||||
* will end up translated to approptiate format on the fly.
|
||||
* The data is streamed out and does *not* need to be
|
||||
* all held in memory at once.
|
||||
*
|
||||
* When the BIO is flushed the output is finalized and any
|
||||
* signatures etc written out.
|
||||
*
|
||||
* The BIO is a 'proper' BIO and can handle non blocking I/O
|
||||
* correctly.
|
||||
*
|
||||
* The usage is simple. The implementation is *not*...
|
||||
/*
|
||||
* The usage is quite simple, initialize an ASN1 structure, get a BIO from it
|
||||
* then any data written through the BIO will end up translated to
|
||||
* approptiate format on the fly. The data is streamed out and does *not*
|
||||
* need to be all held in memory at once. When the BIO is flushed the output
|
||||
* is finalized and any signatures etc written out. The BIO is a 'proper'
|
||||
* BIO and can handle non blocking I/O correctly. The usage is simple. The
|
||||
* implementation is *not*...
|
||||
*/
|
||||
|
||||
/* BIO support data stored in the ASN1 BIO ex_arg */
|
||||
|
||||
typedef struct ndef_aux_st
|
||||
{
|
||||
/* ASN1 structure this BIO refers to */
|
||||
ASN1_VALUE *val;
|
||||
const ASN1_ITEM *it;
|
||||
/* Top of the BIO chain */
|
||||
BIO *ndef_bio;
|
||||
/* Output BIO */
|
||||
BIO *out;
|
||||
/* Boundary where content is inserted */
|
||||
unsigned char **boundary;
|
||||
/* DER buffer start */
|
||||
unsigned char *derbuf;
|
||||
} NDEF_SUPPORT;
|
||||
typedef struct ndef_aux_st {
|
||||
/* ASN1 structure this BIO refers to */
|
||||
ASN1_VALUE *val;
|
||||
const ASN1_ITEM *it;
|
||||
/* Top of the BIO chain */
|
||||
BIO *ndef_bio;
|
||||
/* Output BIO */
|
||||
BIO *out;
|
||||
/* Boundary where content is inserted */
|
||||
unsigned char **boundary;
|
||||
/* DER buffer start */
|
||||
unsigned char *derbuf;
|
||||
} NDEF_SUPPORT;
|
||||
|
||||
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
|
||||
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
|
||||
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
|
||||
void *parg);
|
||||
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg);
|
||||
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg);
|
||||
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
|
||||
void *parg);
|
||||
|
||||
BIO *BIO_new_NDEF(BIO *out, ASN1_VALUE *val, const ASN1_ITEM *it)
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux = NULL;
|
||||
BIO *asn_bio = NULL;
|
||||
const ASN1_AUX *aux = it->funcs;
|
||||
ASN1_STREAM_ARG sarg;
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux = NULL;
|
||||
BIO *asn_bio = NULL;
|
||||
const ASN1_AUX *aux = it->funcs;
|
||||
ASN1_STREAM_ARG sarg;
|
||||
|
||||
if (!aux || !aux->asn1_cb)
|
||||
{
|
||||
ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
}
|
||||
ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
|
||||
asn_bio = BIO_new(BIO_f_asn1());
|
||||
if (!aux || !aux->asn1_cb) {
|
||||
ASN1err(ASN1_F_BIO_NEW_NDEF, ASN1_R_STREAMING_NOT_SUPPORTED);
|
||||
return NULL;
|
||||
}
|
||||
ndef_aux = OPENSSL_malloc(sizeof(NDEF_SUPPORT));
|
||||
asn_bio = BIO_new(BIO_f_asn1());
|
||||
|
||||
/* ASN1 bio needs to be next to output BIO */
|
||||
/* ASN1 bio needs to be next to output BIO */
|
||||
|
||||
out = BIO_push(asn_bio, out);
|
||||
out = BIO_push(asn_bio, out);
|
||||
|
||||
if (!ndef_aux || !asn_bio || !out)
|
||||
goto err;
|
||||
if (!ndef_aux || !asn_bio || !out)
|
||||
goto err;
|
||||
|
||||
BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
|
||||
BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
|
||||
BIO_asn1_set_prefix(asn_bio, ndef_prefix, ndef_prefix_free);
|
||||
BIO_asn1_set_suffix(asn_bio, ndef_suffix, ndef_suffix_free);
|
||||
|
||||
/* Now let callback prepend any digest, cipher etc BIOs
|
||||
* ASN1 structure needs.
|
||||
*/
|
||||
/*
|
||||
* Now let callback prepend any digest, cipher etc BIOs ASN1 structure
|
||||
* needs.
|
||||
*/
|
||||
|
||||
sarg.out = out;
|
||||
sarg.ndef_bio = NULL;
|
||||
sarg.boundary = NULL;
|
||||
sarg.out = out;
|
||||
sarg.ndef_bio = NULL;
|
||||
sarg.boundary = NULL;
|
||||
|
||||
if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
|
||||
goto err;
|
||||
if (aux->asn1_cb(ASN1_OP_STREAM_PRE, &val, it, &sarg) <= 0)
|
||||
goto err;
|
||||
|
||||
ndef_aux->val = val;
|
||||
ndef_aux->it = it;
|
||||
ndef_aux->ndef_bio = sarg.ndef_bio;
|
||||
ndef_aux->boundary = sarg.boundary;
|
||||
ndef_aux->out = out;
|
||||
ndef_aux->val = val;
|
||||
ndef_aux->it = it;
|
||||
ndef_aux->ndef_bio = sarg.ndef_bio;
|
||||
ndef_aux->boundary = sarg.boundary;
|
||||
ndef_aux->out = out;
|
||||
|
||||
BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
|
||||
BIO_ctrl(asn_bio, BIO_C_SET_EX_ARG, 0, ndef_aux);
|
||||
|
||||
return sarg.ndef_bio;
|
||||
return sarg.ndef_bio;
|
||||
|
||||
err:
|
||||
if (asn_bio)
|
||||
BIO_free(asn_bio);
|
||||
if (ndef_aux)
|
||||
OPENSSL_free(ndef_aux);
|
||||
return NULL;
|
||||
}
|
||||
err:
|
||||
if (asn_bio)
|
||||
BIO_free(asn_bio);
|
||||
if (ndef_aux)
|
||||
OPENSSL_free(ndef_aux);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int ndef_prefix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux;
|
||||
unsigned char *p;
|
||||
int derlen;
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux;
|
||||
unsigned char *p;
|
||||
int derlen;
|
||||
|
||||
if (!parg)
|
||||
return 0;
|
||||
if (!parg)
|
||||
return 0;
|
||||
|
||||
ndef_aux = *(NDEF_SUPPORT **)parg;
|
||||
ndef_aux = *(NDEF_SUPPORT **)parg;
|
||||
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
|
||||
p = OPENSSL_malloc(derlen);
|
||||
ndef_aux->derbuf = p;
|
||||
*pbuf = p;
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
|
||||
p = OPENSSL_malloc(derlen);
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
if (!*ndef_aux->boundary)
|
||||
return 0;
|
||||
ndef_aux->derbuf = p;
|
||||
*pbuf = p;
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
|
||||
|
||||
*plen = *ndef_aux->boundary - *pbuf;
|
||||
if (!*ndef_aux->boundary)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
*plen = *ndef_aux->boundary - *pbuf;
|
||||
|
||||
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (!parg)
|
||||
return 0;
|
||||
static int ndef_prefix_free(BIO *b, unsigned char **pbuf, int *plen,
|
||||
void *parg)
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux;
|
||||
|
||||
ndef_aux = *(NDEF_SUPPORT **)parg;
|
||||
if (!parg)
|
||||
return 0;
|
||||
|
||||
if (ndef_aux->derbuf)
|
||||
OPENSSL_free(ndef_aux->derbuf);
|
||||
ndef_aux = *(NDEF_SUPPORT **)parg;
|
||||
|
||||
ndef_aux->derbuf = NULL;
|
||||
*pbuf = NULL;
|
||||
*plen = 0;
|
||||
return 1;
|
||||
}
|
||||
if (ndef_aux->derbuf)
|
||||
OPENSSL_free(ndef_aux->derbuf);
|
||||
|
||||
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen, void *parg)
|
||||
{
|
||||
NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
|
||||
if (!ndef_prefix_free(b, pbuf, plen, parg))
|
||||
return 0;
|
||||
OPENSSL_free(*pndef_aux);
|
||||
*pndef_aux = NULL;
|
||||
return 1;
|
||||
}
|
||||
ndef_aux->derbuf = NULL;
|
||||
*pbuf = NULL;
|
||||
*plen = 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ndef_suffix_free(BIO *b, unsigned char **pbuf, int *plen,
|
||||
void *parg)
|
||||
{
|
||||
NDEF_SUPPORT **pndef_aux = (NDEF_SUPPORT **)parg;
|
||||
if (!ndef_prefix_free(b, pbuf, plen, parg))
|
||||
return 0;
|
||||
OPENSSL_free(*pndef_aux);
|
||||
*pndef_aux = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int ndef_suffix(BIO *b, unsigned char **pbuf, int *plen, void *parg)
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux;
|
||||
unsigned char *p;
|
||||
int derlen;
|
||||
const ASN1_AUX *aux;
|
||||
ASN1_STREAM_ARG sarg;
|
||||
{
|
||||
NDEF_SUPPORT *ndef_aux;
|
||||
unsigned char *p;
|
||||
int derlen;
|
||||
const ASN1_AUX *aux;
|
||||
ASN1_STREAM_ARG sarg;
|
||||
|
||||
if (!parg)
|
||||
return 0;
|
||||
if (!parg)
|
||||
return 0;
|
||||
|
||||
ndef_aux = *(NDEF_SUPPORT **)parg;
|
||||
ndef_aux = *(NDEF_SUPPORT **)parg;
|
||||
|
||||
aux = ndef_aux->it->funcs;
|
||||
aux = ndef_aux->it->funcs;
|
||||
|
||||
/* Finalize structures */
|
||||
sarg.ndef_bio = ndef_aux->ndef_bio;
|
||||
sarg.out = ndef_aux->out;
|
||||
sarg.boundary = ndef_aux->boundary;
|
||||
if (aux->asn1_cb(ASN1_OP_STREAM_POST,
|
||||
&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
|
||||
return 0;
|
||||
/* Finalize structures */
|
||||
sarg.ndef_bio = ndef_aux->ndef_bio;
|
||||
sarg.out = ndef_aux->out;
|
||||
sarg.boundary = ndef_aux->boundary;
|
||||
if (aux->asn1_cb(ASN1_OP_STREAM_POST,
|
||||
&ndef_aux->val, ndef_aux->it, &sarg) <= 0)
|
||||
return 0;
|
||||
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
|
||||
p = OPENSSL_malloc(derlen);
|
||||
ndef_aux->derbuf = p;
|
||||
*pbuf = p;
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, NULL, ndef_aux->it);
|
||||
p = OPENSSL_malloc(derlen);
|
||||
if (!p)
|
||||
return 0;
|
||||
|
||||
if (!*ndef_aux->boundary)
|
||||
return 0;
|
||||
*pbuf = *ndef_aux->boundary;
|
||||
*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
|
||||
ndef_aux->derbuf = p;
|
||||
*pbuf = p;
|
||||
derlen = ASN1_item_ndef_i2d(ndef_aux->val, &p, ndef_aux->it);
|
||||
|
||||
return 1;
|
||||
}
|
||||
if (!*ndef_aux->boundary)
|
||||
return 0;
|
||||
*pbuf = *ndef_aux->boundary;
|
||||
*plen = derlen - (*ndef_aux->boundary - ndef_aux->derbuf);
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1,15 +1,15 @@
|
||||
/* Auto generated with chartype.pl script.
|
||||
* Mask of various character properties
|
||||
/*
|
||||
* Auto generated with chartype.pl script. Mask of various character
|
||||
* properties
|
||||
*/
|
||||
|
||||
static const unsigned char char_type[] = {
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
120, 0, 1,40, 0, 0, 0,16,16,16, 0,25,25,16,16,16,
|
||||
16,16,16,16,16,16,16,16,16,16,16, 9, 9,16, 9,16,
|
||||
0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
|
||||
16,16,16,16,16,16,16,16,16,16,16, 0, 1, 0, 0, 0,
|
||||
0,16,16,16,16,16,16,16,16,16,16,16,16,16,16,16,
|
||||
16,16,16,16,16,16,16,16,16,16,16, 0, 0, 0, 0, 2
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2,
|
||||
120, 0, 1, 40, 0, 0, 0, 16, 16, 16, 0, 25, 25, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 9, 9, 16, 9, 16,
|
||||
0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 1, 0, 0, 0,
|
||||
0, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16,
|
||||
16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 16, 0, 0, 0, 0, 2
|
||||
};
|
||||
|
||||
|
||||
@ -1,5 +1,8 @@
|
||||
#!/usr/local/bin/perl -w
|
||||
|
||||
# Written by Dr Stephen N Henson (steve@openssl.org).
|
||||
# Licensed under the terms of the OpenSSL license.
|
||||
|
||||
use strict;
|
||||
|
||||
my ($i, @arr);
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,109 +62,114 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
#include <openssl/engine.h>
|
||||
# include <openssl/engine.h>
|
||||
#endif
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include "asn1_locl.h"
|
||||
|
||||
EVP_PKEY *d2i_PrivateKey(int type, EVP_PKEY **a, const unsigned char **pp,
|
||||
long length)
|
||||
{
|
||||
EVP_PKEY *ret;
|
||||
long length)
|
||||
{
|
||||
EVP_PKEY *ret;
|
||||
const unsigned char *p = *pp;
|
||||
|
||||
if ((a == NULL) || (*a == NULL))
|
||||
{
|
||||
if ((ret=EVP_PKEY_new()) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_EVP_LIB);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
ret= *a;
|
||||
if ((a == NULL) || (*a == NULL)) {
|
||||
if ((ret = EVP_PKEY_new()) == NULL) {
|
||||
ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_EVP_LIB);
|
||||
return (NULL);
|
||||
}
|
||||
} else {
|
||||
ret = *a;
|
||||
#ifndef OPENSSL_NO_ENGINE
|
||||
if (ret->engine)
|
||||
{
|
||||
ENGINE_finish(ret->engine);
|
||||
ret->engine = NULL;
|
||||
}
|
||||
if (ret->engine) {
|
||||
ENGINE_finish(ret->engine);
|
||||
ret->engine = NULL;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if (!EVP_PKEY_set_type(ret, type))
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_PRIVATEKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_PKEY_set_type(ret, type)) {
|
||||
ASN1err(ASN1_F_D2I_PRIVATEKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if (!ret->ameth->old_priv_decode ||
|
||||
!ret->ameth->old_priv_decode(ret, pp, length))
|
||||
{
|
||||
if (ret->ameth->priv_decode)
|
||||
{
|
||||
PKCS8_PRIV_KEY_INFO *p8=NULL;
|
||||
p8=d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
|
||||
if (!p8) goto err;
|
||||
EVP_PKEY_free(ret);
|
||||
ret = EVP_PKCS82PKEY(p8);
|
||||
PKCS8_PRIV_KEY_INFO_free(p8);
|
||||
if (!ret->ameth->old_priv_decode ||
|
||||
!ret->ameth->old_priv_decode(ret, &p, length)) {
|
||||
if (ret->ameth->priv_decode) {
|
||||
PKCS8_PRIV_KEY_INFO *p8 = NULL;
|
||||
p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
|
||||
if (!p8)
|
||||
goto err;
|
||||
EVP_PKEY_free(ret);
|
||||
ret = EVP_PKCS82PKEY(p8);
|
||||
PKCS8_PRIV_KEY_INFO_free(p8);
|
||||
if (ret == NULL)
|
||||
goto err;
|
||||
} else {
|
||||
ASN1err(ASN1_F_D2I_PRIVATEKEY, ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
*pp = p;
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
return (ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
EVP_PKEY_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
}
|
||||
else
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_PRIVATEKEY,ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
if (a != NULL) (*a)=ret;
|
||||
return(ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
/* This works like d2i_PrivateKey() except it automatically works out the type */
|
||||
/*
|
||||
* This works like d2i_PrivateKey() except it automatically works out the
|
||||
* type
|
||||
*/
|
||||
|
||||
EVP_PKEY *d2i_AutoPrivateKey(EVP_PKEY **a, const unsigned char **pp,
|
||||
long length)
|
||||
long length)
|
||||
{
|
||||
STACK_OF(ASN1_TYPE) *inkey;
|
||||
const unsigned char *p;
|
||||
int keytype;
|
||||
p = *pp;
|
||||
/* Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE):
|
||||
* by analyzing it we can determine the passed structure: this
|
||||
* assumes the input is surrounded by an ASN1 SEQUENCE.
|
||||
*/
|
||||
inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
|
||||
/* Since we only need to discern "traditional format" RSA and DSA
|
||||
* keys we can just count the elements.
|
||||
*/
|
||||
if(sk_ASN1_TYPE_num(inkey) == 6)
|
||||
keytype = EVP_PKEY_DSA;
|
||||
else if (sk_ASN1_TYPE_num(inkey) == 4)
|
||||
keytype = EVP_PKEY_EC;
|
||||
else if (sk_ASN1_TYPE_num(inkey) == 3)
|
||||
{ /* This seems to be PKCS8, not traditional format */
|
||||
PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL,pp,length);
|
||||
EVP_PKEY *ret;
|
||||
STACK_OF(ASN1_TYPE) *inkey;
|
||||
const unsigned char *p;
|
||||
int keytype;
|
||||
p = *pp;
|
||||
/*
|
||||
* Dirty trick: read in the ASN1 data into a STACK_OF(ASN1_TYPE): by
|
||||
* analyzing it we can determine the passed structure: this assumes the
|
||||
* input is surrounded by an ASN1 SEQUENCE.
|
||||
*/
|
||||
inkey = d2i_ASN1_SEQUENCE_ANY(NULL, &p, length);
|
||||
p = *pp;
|
||||
/*
|
||||
* Since we only need to discern "traditional format" RSA and DSA keys we
|
||||
* can just count the elements.
|
||||
*/
|
||||
if (sk_ASN1_TYPE_num(inkey) == 6)
|
||||
keytype = EVP_PKEY_DSA;
|
||||
else if (sk_ASN1_TYPE_num(inkey) == 4)
|
||||
keytype = EVP_PKEY_EC;
|
||||
else if (sk_ASN1_TYPE_num(inkey) == 3) { /* This seems to be PKCS8, not
|
||||
* traditional format */
|
||||
PKCS8_PRIV_KEY_INFO *p8 = d2i_PKCS8_PRIV_KEY_INFO(NULL, &p, length);
|
||||
EVP_PKEY *ret;
|
||||
|
||||
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
|
||||
if (!p8)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
|
||||
return NULL;
|
||||
}
|
||||
ret = EVP_PKCS82PKEY(p8);
|
||||
PKCS8_PRIV_KEY_INFO_free(p8);
|
||||
if (a) {
|
||||
*a = ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
else keytype = EVP_PKEY_RSA;
|
||||
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
|
||||
return d2i_PrivateKey(keytype, a, pp, length);
|
||||
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
|
||||
if (!p8) {
|
||||
ASN1err(ASN1_F_D2I_AUTOPRIVATEKEY,
|
||||
ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
|
||||
return NULL;
|
||||
}
|
||||
ret = EVP_PKCS82PKEY(p8);
|
||||
PKCS8_PRIV_KEY_INFO_free(p8);
|
||||
if (ret == NULL)
|
||||
return NULL;
|
||||
*pp = p;
|
||||
if (a) {
|
||||
*a = ret;
|
||||
}
|
||||
return ret;
|
||||
} else
|
||||
keytype = EVP_PKEY_RSA;
|
||||
sk_ASN1_TYPE_pop_free(inkey, ASN1_TYPE_free);
|
||||
return d2i_PrivateKey(keytype, a, pp, length);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -63,77 +63,74 @@
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/asn1.h>
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
#include <openssl/rsa.h>
|
||||
# include <openssl/rsa.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
#include <openssl/dsa.h>
|
||||
# include <openssl/dsa.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
#include <openssl/ec.h>
|
||||
# include <openssl/ec.h>
|
||||
#endif
|
||||
|
||||
EVP_PKEY *d2i_PublicKey(int type, EVP_PKEY **a, const unsigned char **pp,
|
||||
long length)
|
||||
{
|
||||
EVP_PKEY *ret;
|
||||
long length)
|
||||
{
|
||||
EVP_PKEY *ret;
|
||||
|
||||
if ((a == NULL) || (*a == NULL))
|
||||
{
|
||||
if ((ret=EVP_PKEY_new()) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB);
|
||||
return(NULL);
|
||||
}
|
||||
}
|
||||
else ret= *a;
|
||||
if ((a == NULL) || (*a == NULL)) {
|
||||
if ((ret = EVP_PKEY_new()) == NULL) {
|
||||
ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
|
||||
return (NULL);
|
||||
}
|
||||
} else
|
||||
ret = *a;
|
||||
|
||||
if (!EVP_PKEY_set_type(ret, type))
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
if (!EVP_PKEY_set_type(ret, type)) {
|
||||
ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_EVP_LIB);
|
||||
goto err;
|
||||
}
|
||||
|
||||
switch (EVP_PKEY_id(ret))
|
||||
{
|
||||
switch (EVP_PKEY_id(ret)) {
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
case EVP_PKEY_RSA:
|
||||
if ((ret->pkey.rsa=d2i_RSAPublicKey(NULL,
|
||||
(const unsigned char **)pp,length)) == NULL) /* TMP UGLY CAST */
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case EVP_PKEY_RSA:
|
||||
/* TMP UGLY CAST */
|
||||
if ((ret->pkey.rsa = d2i_RSAPublicKey(NULL,
|
||||
(const unsigned char **)pp,
|
||||
length)) == NULL) {
|
||||
ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
case EVP_PKEY_DSA:
|
||||
if (!d2i_DSAPublicKey(&(ret->pkey.dsa),
|
||||
(const unsigned char **)pp,length)) /* TMP UGLY CAST */
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_PUBLICKEY,ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case EVP_PKEY_DSA:
|
||||
/* TMP UGLY CAST */
|
||||
if (!d2i_DSAPublicKey(&(ret->pkey.dsa),
|
||||
(const unsigned char **)pp, length)) {
|
||||
ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
case EVP_PKEY_EC:
|
||||
if (!o2i_ECPublicKey(&(ret->pkey.ec),
|
||||
(const unsigned char **)pp, length))
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
case EVP_PKEY_EC:
|
||||
if (!o2i_ECPublicKey(&(ret->pkey.ec),
|
||||
(const unsigned char **)pp, length)) {
|
||||
ASN1err(ASN1_F_D2I_PUBLICKEY, ERR_R_ASN1_LIB);
|
||||
goto err;
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
default:
|
||||
ASN1err(ASN1_F_D2I_PUBLICKEY,ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
|
||||
goto err;
|
||||
/* break; */
|
||||
}
|
||||
if (a != NULL) (*a)=ret;
|
||||
return(ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret))) EVP_PKEY_free(ret);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
default:
|
||||
ASN1err(ASN1_F_D2I_PUBLICKEY, ASN1_R_UNKNOWN_PUBLIC_KEY_TYPE);
|
||||
goto err;
|
||||
/* break; */
|
||||
}
|
||||
if (a != NULL)
|
||||
(*a) = ret;
|
||||
return (ret);
|
||||
err:
|
||||
if ((ret != NULL) && ((a == NULL) || (*a != ret)))
|
||||
EVP_PKEY_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,128 +62,134 @@
|
||||
#include <openssl/asn1_mac.h>
|
||||
|
||||
int ASN1_TYPE_set_octetstring(ASN1_TYPE *a, unsigned char *data, int len)
|
||||
{
|
||||
ASN1_STRING *os;
|
||||
{
|
||||
ASN1_STRING *os;
|
||||
|
||||
if ((os=M_ASN1_OCTET_STRING_new()) == NULL) return(0);
|
||||
if (!M_ASN1_OCTET_STRING_set(os,data,len)) return(0);
|
||||
ASN1_TYPE_set(a,V_ASN1_OCTET_STRING,os);
|
||||
return(1);
|
||||
}
|
||||
if ((os = M_ASN1_OCTET_STRING_new()) == NULL)
|
||||
return (0);
|
||||
if (!M_ASN1_OCTET_STRING_set(os, data, len)) {
|
||||
M_ASN1_OCTET_STRING_free(os);
|
||||
return 0;
|
||||
}
|
||||
ASN1_TYPE_set(a, V_ASN1_OCTET_STRING, os);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* int max_len: for returned value */
|
||||
int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data,
|
||||
int max_len)
|
||||
{
|
||||
int ret,num;
|
||||
unsigned char *p;
|
||||
int ASN1_TYPE_get_octetstring(ASN1_TYPE *a, unsigned char *data, int max_len)
|
||||
{
|
||||
int ret, num;
|
||||
unsigned char *p;
|
||||
|
||||
if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL))
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING,ASN1_R_DATA_IS_WRONG);
|
||||
return(-1);
|
||||
}
|
||||
p=M_ASN1_STRING_data(a->value.octet_string);
|
||||
ret=M_ASN1_STRING_length(a->value.octet_string);
|
||||
if (ret < max_len)
|
||||
num=ret;
|
||||
else
|
||||
num=max_len;
|
||||
memcpy(data,p,num);
|
||||
return(ret);
|
||||
}
|
||||
if ((a->type != V_ASN1_OCTET_STRING) || (a->value.octet_string == NULL)) {
|
||||
ASN1err(ASN1_F_ASN1_TYPE_GET_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
|
||||
return (-1);
|
||||
}
|
||||
p = M_ASN1_STRING_data(a->value.octet_string);
|
||||
ret = M_ASN1_STRING_length(a->value.octet_string);
|
||||
if (ret < max_len)
|
||||
num = ret;
|
||||
else
|
||||
num = max_len;
|
||||
memcpy(data, p, num);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int ASN1_TYPE_set_int_octetstring(ASN1_TYPE *a, long num, unsigned char *data,
|
||||
int len)
|
||||
{
|
||||
int n,size;
|
||||
ASN1_OCTET_STRING os,*osp;
|
||||
ASN1_INTEGER in;
|
||||
unsigned char *p;
|
||||
unsigned char buf[32]; /* when they have 256bit longs,
|
||||
* I'll be in trouble */
|
||||
in.data=buf;
|
||||
in.length=32;
|
||||
os.data=data;
|
||||
os.type=V_ASN1_OCTET_STRING;
|
||||
os.length=len;
|
||||
ASN1_INTEGER_set(&in,num);
|
||||
n = i2d_ASN1_INTEGER(&in,NULL);
|
||||
n+=M_i2d_ASN1_OCTET_STRING(&os,NULL);
|
||||
int len)
|
||||
{
|
||||
int n, size;
|
||||
ASN1_OCTET_STRING os, *osp;
|
||||
ASN1_INTEGER in;
|
||||
unsigned char *p;
|
||||
unsigned char buf[32]; /* when they have 256bit longs, I'll be in
|
||||
* trouble */
|
||||
in.data = buf;
|
||||
in.length = 32;
|
||||
os.data = data;
|
||||
os.type = V_ASN1_OCTET_STRING;
|
||||
os.length = len;
|
||||
ASN1_INTEGER_set(&in, num);
|
||||
n = i2d_ASN1_INTEGER(&in, NULL);
|
||||
n += M_i2d_ASN1_OCTET_STRING(&os, NULL);
|
||||
|
||||
size=ASN1_object_size(1,n,V_ASN1_SEQUENCE);
|
||||
size = ASN1_object_size(1, n, V_ASN1_SEQUENCE);
|
||||
|
||||
if ((osp=ASN1_STRING_new()) == NULL) return(0);
|
||||
/* Grow the 'string' */
|
||||
if (!ASN1_STRING_set(osp,NULL,size))
|
||||
{
|
||||
ASN1_STRING_free(osp);
|
||||
return(0);
|
||||
}
|
||||
if ((osp = ASN1_STRING_new()) == NULL)
|
||||
return (0);
|
||||
/* Grow the 'string' */
|
||||
if (!ASN1_STRING_set(osp, NULL, size)) {
|
||||
ASN1_STRING_free(osp);
|
||||
return (0);
|
||||
}
|
||||
|
||||
M_ASN1_STRING_length_set(osp, size);
|
||||
p=M_ASN1_STRING_data(osp);
|
||||
M_ASN1_STRING_length_set(osp, size);
|
||||
p = M_ASN1_STRING_data(osp);
|
||||
|
||||
ASN1_put_object(&p,1,n,V_ASN1_SEQUENCE,V_ASN1_UNIVERSAL);
|
||||
i2d_ASN1_INTEGER(&in,&p);
|
||||
M_i2d_ASN1_OCTET_STRING(&os,&p);
|
||||
ASN1_put_object(&p, 1, n, V_ASN1_SEQUENCE, V_ASN1_UNIVERSAL);
|
||||
i2d_ASN1_INTEGER(&in, &p);
|
||||
M_i2d_ASN1_OCTET_STRING(&os, &p);
|
||||
|
||||
ASN1_TYPE_set(a,V_ASN1_SEQUENCE,osp);
|
||||
return(1);
|
||||
}
|
||||
ASN1_TYPE_set(a, V_ASN1_SEQUENCE, osp);
|
||||
return (1);
|
||||
}
|
||||
|
||||
/* we return the actual length..., num may be missing, in which
|
||||
* case, set it to zero */
|
||||
/*
|
||||
* we return the actual length..., num may be missing, in which case, set it
|
||||
* to zero
|
||||
*/
|
||||
/* int max_len: for returned value */
|
||||
int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num, unsigned char *data,
|
||||
int max_len)
|
||||
{
|
||||
int ret= -1,n;
|
||||
ASN1_INTEGER *ai=NULL;
|
||||
ASN1_OCTET_STRING *os=NULL;
|
||||
const unsigned char *p;
|
||||
long length;
|
||||
ASN1_const_CTX c;
|
||||
int ASN1_TYPE_get_int_octetstring(ASN1_TYPE *a, long *num,
|
||||
unsigned char *data, int max_len)
|
||||
{
|
||||
int ret = -1, n;
|
||||
ASN1_INTEGER *ai = NULL;
|
||||
ASN1_OCTET_STRING *os = NULL;
|
||||
const unsigned char *p;
|
||||
long length;
|
||||
ASN1_const_CTX c;
|
||||
|
||||
if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL))
|
||||
{
|
||||
goto err;
|
||||
}
|
||||
p=M_ASN1_STRING_data(a->value.sequence);
|
||||
length=M_ASN1_STRING_length(a->value.sequence);
|
||||
if ((a->type != V_ASN1_SEQUENCE) || (a->value.sequence == NULL)) {
|
||||
goto err;
|
||||
}
|
||||
p = M_ASN1_STRING_data(a->value.sequence);
|
||||
length = M_ASN1_STRING_length(a->value.sequence);
|
||||
|
||||
c.pp= &p;
|
||||
c.p=p;
|
||||
c.max=p+length;
|
||||
c.error=ASN1_R_DATA_IS_WRONG;
|
||||
c.pp = &p;
|
||||
c.p = p;
|
||||
c.max = p + length;
|
||||
c.error = ASN1_R_DATA_IS_WRONG;
|
||||
|
||||
M_ASN1_D2I_start_sequence();
|
||||
c.q=c.p;
|
||||
if ((ai=d2i_ASN1_INTEGER(NULL,&c.p,c.slen)) == NULL) goto err;
|
||||
c.slen-=(c.p-c.q);
|
||||
c.q=c.p;
|
||||
if ((os=d2i_ASN1_OCTET_STRING(NULL,&c.p,c.slen)) == NULL) goto err;
|
||||
c.slen-=(c.p-c.q);
|
||||
if (!M_ASN1_D2I_end_sequence()) goto err;
|
||||
M_ASN1_D2I_start_sequence();
|
||||
c.q = c.p;
|
||||
if ((ai = d2i_ASN1_INTEGER(NULL, &c.p, c.slen)) == NULL)
|
||||
goto err;
|
||||
c.slen -= (c.p - c.q);
|
||||
c.q = c.p;
|
||||
if ((os = d2i_ASN1_OCTET_STRING(NULL, &c.p, c.slen)) == NULL)
|
||||
goto err;
|
||||
c.slen -= (c.p - c.q);
|
||||
if (!M_ASN1_D2I_end_sequence())
|
||||
goto err;
|
||||
|
||||
if (num != NULL)
|
||||
*num=ASN1_INTEGER_get(ai);
|
||||
if (num != NULL)
|
||||
*num = ASN1_INTEGER_get(ai);
|
||||
|
||||
ret=M_ASN1_STRING_length(os);
|
||||
if (max_len > ret)
|
||||
n=ret;
|
||||
else
|
||||
n=max_len;
|
||||
|
||||
if (data != NULL)
|
||||
memcpy(data,M_ASN1_STRING_data(os),n);
|
||||
if (0)
|
||||
{
|
||||
err:
|
||||
ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING,ASN1_R_DATA_IS_WRONG);
|
||||
}
|
||||
if (os != NULL) M_ASN1_OCTET_STRING_free(os);
|
||||
if (ai != NULL) M_ASN1_INTEGER_free(ai);
|
||||
return(ret);
|
||||
}
|
||||
ret = M_ASN1_STRING_length(os);
|
||||
if (max_len > ret)
|
||||
n = ret;
|
||||
else
|
||||
n = max_len;
|
||||
|
||||
if (data != NULL)
|
||||
memcpy(data, M_ASN1_STRING_data(os), n);
|
||||
if (0) {
|
||||
err:
|
||||
ASN1err(ASN1_F_ASN1_TYPE_GET_INT_OCTETSTRING, ASN1_R_DATA_IS_WRONG);
|
||||
}
|
||||
if (os != NULL)
|
||||
M_ASN1_OCTET_STRING_free(os);
|
||||
if (ai != NULL)
|
||||
M_ASN1_INTEGER_free(ai);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -64,144 +64,140 @@
|
||||
/* Based on a_int.c: equivalent ENUMERATED functions */
|
||||
|
||||
int i2a_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *a)
|
||||
{
|
||||
int i,n=0;
|
||||
static const char *h="0123456789ABCDEF";
|
||||
char buf[2];
|
||||
{
|
||||
int i, n = 0;
|
||||
static const char *h = "0123456789ABCDEF";
|
||||
char buf[2];
|
||||
|
||||
if (a == NULL) return(0);
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
|
||||
if (a->length == 0)
|
||||
{
|
||||
if (BIO_write(bp,"00",2) != 2) goto err;
|
||||
n=2;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i<a->length; i++)
|
||||
{
|
||||
if ((i != 0) && (i%35 == 0))
|
||||
{
|
||||
if (BIO_write(bp,"\\\n",2) != 2) goto err;
|
||||
n+=2;
|
||||
}
|
||||
buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
|
||||
buf[1]=h[((unsigned char)a->data[i] )&0x0f];
|
||||
if (BIO_write(bp,buf,2) != 2) goto err;
|
||||
n+=2;
|
||||
}
|
||||
}
|
||||
return(n);
|
||||
err:
|
||||
return(-1);
|
||||
}
|
||||
if (a->length == 0) {
|
||||
if (BIO_write(bp, "00", 2) != 2)
|
||||
goto err;
|
||||
n = 2;
|
||||
} else {
|
||||
for (i = 0; i < a->length; i++) {
|
||||
if ((i != 0) && (i % 35 == 0)) {
|
||||
if (BIO_write(bp, "\\\n", 2) != 2)
|
||||
goto err;
|
||||
n += 2;
|
||||
}
|
||||
buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
|
||||
buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
|
||||
if (BIO_write(bp, buf, 2) != 2)
|
||||
goto err;
|
||||
n += 2;
|
||||
}
|
||||
}
|
||||
return (n);
|
||||
err:
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int a2i_ASN1_ENUMERATED(BIO *bp, ASN1_ENUMERATED *bs, char *buf, int size)
|
||||
{
|
||||
int ret=0;
|
||||
int i,j,k,m,n,again,bufsize;
|
||||
unsigned char *s=NULL,*sp;
|
||||
unsigned char *bufp;
|
||||
int num=0,slen=0,first=1;
|
||||
{
|
||||
int ret = 0;
|
||||
int i, j, k, m, n, again, bufsize;
|
||||
unsigned char *s = NULL, *sp;
|
||||
unsigned char *bufp;
|
||||
int num = 0, slen = 0, first = 1;
|
||||
|
||||
bs->type=V_ASN1_ENUMERATED;
|
||||
bs->type = V_ASN1_ENUMERATED;
|
||||
|
||||
bufsize=BIO_gets(bp,buf,size);
|
||||
for (;;)
|
||||
{
|
||||
if (bufsize < 1) goto err_sl;
|
||||
i=bufsize;
|
||||
if (buf[i-1] == '\n') buf[--i]='\0';
|
||||
if (i == 0) goto err_sl;
|
||||
if (buf[i-1] == '\r') buf[--i]='\0';
|
||||
if (i == 0) goto err_sl;
|
||||
again=(buf[i-1] == '\\');
|
||||
bufsize = BIO_gets(bp, buf, size);
|
||||
for (;;) {
|
||||
if (bufsize < 1)
|
||||
goto err_sl;
|
||||
i = bufsize;
|
||||
if (buf[i - 1] == '\n')
|
||||
buf[--i] = '\0';
|
||||
if (i == 0)
|
||||
goto err_sl;
|
||||
if (buf[i - 1] == '\r')
|
||||
buf[--i] = '\0';
|
||||
if (i == 0)
|
||||
goto err_sl;
|
||||
again = (buf[i - 1] == '\\');
|
||||
|
||||
for (j=0; j<i; j++)
|
||||
{
|
||||
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
|
||||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
|
||||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
|
||||
{
|
||||
i=j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[i]='\0';
|
||||
/* We have now cleared all the crap off the end of the
|
||||
* line */
|
||||
if (i < 2) goto err_sl;
|
||||
|
||||
bufp=(unsigned char *)buf;
|
||||
if (first)
|
||||
{
|
||||
first=0;
|
||||
if ((bufp[0] == '0') && (buf[1] == '0'))
|
||||
{
|
||||
bufp+=2;
|
||||
i-=2;
|
||||
}
|
||||
}
|
||||
k=0;
|
||||
i-=again;
|
||||
if (i%2 != 0)
|
||||
{
|
||||
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_ODD_NUMBER_OF_CHARS);
|
||||
goto err;
|
||||
}
|
||||
i/=2;
|
||||
if (num+i > slen)
|
||||
{
|
||||
if (s == NULL)
|
||||
sp=(unsigned char *)OPENSSL_malloc(
|
||||
(unsigned int)num+i*2);
|
||||
else
|
||||
sp=(unsigned char *)OPENSSL_realloc(s,
|
||||
(unsigned int)num+i*2);
|
||||
if (sp == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ERR_R_MALLOC_FAILURE);
|
||||
if (s != NULL) OPENSSL_free(s);
|
||||
goto err;
|
||||
}
|
||||
s=sp;
|
||||
slen=num+i*2;
|
||||
}
|
||||
for (j=0; j<i; j++,k+=2)
|
||||
{
|
||||
for (n=0; n<2; n++)
|
||||
{
|
||||
m=bufp[k+n];
|
||||
if ((m >= '0') && (m <= '9'))
|
||||
m-='0';
|
||||
else if ((m >= 'a') && (m <= 'f'))
|
||||
m=m-'a'+10;
|
||||
else if ((m >= 'A') && (m <= 'F'))
|
||||
m=m-'A'+10;
|
||||
else
|
||||
{
|
||||
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_NON_HEX_CHARACTERS);
|
||||
goto err;
|
||||
}
|
||||
s[num+j]<<=4;
|
||||
s[num+j]|=m;
|
||||
}
|
||||
}
|
||||
num+=i;
|
||||
if (again)
|
||||
bufsize=BIO_gets(bp,buf,size);
|
||||
else
|
||||
break;
|
||||
}
|
||||
bs->length=num;
|
||||
bs->data=s;
|
||||
ret=1;
|
||||
err:
|
||||
if (0)
|
||||
{
|
||||
err_sl:
|
||||
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,ASN1_R_SHORT_LINE);
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
for (j = 0; j < i; j++) {
|
||||
if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
|
||||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
|
||||
((buf[j] >= 'A') && (buf[j] <= 'F')))) {
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[i] = '\0';
|
||||
/*
|
||||
* We have now cleared all the crap off the end of the line
|
||||
*/
|
||||
if (i < 2)
|
||||
goto err_sl;
|
||||
|
||||
bufp = (unsigned char *)buf;
|
||||
if (first) {
|
||||
first = 0;
|
||||
if ((bufp[0] == '0') && (buf[1] == '0')) {
|
||||
bufp += 2;
|
||||
i -= 2;
|
||||
}
|
||||
}
|
||||
k = 0;
|
||||
i -= again;
|
||||
if (i % 2 != 0) {
|
||||
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_ODD_NUMBER_OF_CHARS);
|
||||
goto err;
|
||||
}
|
||||
i /= 2;
|
||||
if (num + i > slen) {
|
||||
if (s == NULL)
|
||||
sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
|
||||
i * 2);
|
||||
else
|
||||
sp = (unsigned char *)OPENSSL_realloc(s,
|
||||
(unsigned int)num +
|
||||
i * 2);
|
||||
if (sp == NULL) {
|
||||
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ERR_R_MALLOC_FAILURE);
|
||||
if (s != NULL)
|
||||
OPENSSL_free(s);
|
||||
goto err;
|
||||
}
|
||||
s = sp;
|
||||
slen = num + i * 2;
|
||||
}
|
||||
for (j = 0; j < i; j++, k += 2) {
|
||||
for (n = 0; n < 2; n++) {
|
||||
m = bufp[k + n];
|
||||
if ((m >= '0') && (m <= '9'))
|
||||
m -= '0';
|
||||
else if ((m >= 'a') && (m <= 'f'))
|
||||
m = m - 'a' + 10;
|
||||
else if ((m >= 'A') && (m <= 'F'))
|
||||
m = m - 'A' + 10;
|
||||
else {
|
||||
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED,
|
||||
ASN1_R_NON_HEX_CHARACTERS);
|
||||
goto err;
|
||||
}
|
||||
s[num + j] <<= 4;
|
||||
s[num + j] |= m;
|
||||
}
|
||||
}
|
||||
num += i;
|
||||
if (again)
|
||||
bufsize = BIO_gets(bp, buf, size);
|
||||
else
|
||||
break;
|
||||
}
|
||||
bs->length = num;
|
||||
bs->data = s;
|
||||
ret = 1;
|
||||
err:
|
||||
if (0) {
|
||||
err_sl:
|
||||
ASN1err(ASN1_F_A2I_ASN1_ENUMERATED, ASN1_R_SHORT_LINE);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,158 +62,154 @@
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
int i2a_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *a)
|
||||
{
|
||||
int i,n=0;
|
||||
static const char *h="0123456789ABCDEF";
|
||||
char buf[2];
|
||||
{
|
||||
int i, n = 0;
|
||||
static const char *h = "0123456789ABCDEF";
|
||||
char buf[2];
|
||||
|
||||
if (a == NULL) return(0);
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
|
||||
if (a->type & V_ASN1_NEG)
|
||||
{
|
||||
if (BIO_write(bp, "-", 1) != 1) goto err;
|
||||
n = 1;
|
||||
}
|
||||
if (a->type & V_ASN1_NEG) {
|
||||
if (BIO_write(bp, "-", 1) != 1)
|
||||
goto err;
|
||||
n = 1;
|
||||
}
|
||||
|
||||
if (a->length == 0)
|
||||
{
|
||||
if (BIO_write(bp,"00",2) != 2) goto err;
|
||||
n += 2;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i<a->length; i++)
|
||||
{
|
||||
if ((i != 0) && (i%35 == 0))
|
||||
{
|
||||
if (BIO_write(bp,"\\\n",2) != 2) goto err;
|
||||
n+=2;
|
||||
}
|
||||
buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
|
||||
buf[1]=h[((unsigned char)a->data[i] )&0x0f];
|
||||
if (BIO_write(bp,buf,2) != 2) goto err;
|
||||
n+=2;
|
||||
}
|
||||
}
|
||||
return(n);
|
||||
err:
|
||||
return(-1);
|
||||
}
|
||||
if (a->length == 0) {
|
||||
if (BIO_write(bp, "00", 2) != 2)
|
||||
goto err;
|
||||
n += 2;
|
||||
} else {
|
||||
for (i = 0; i < a->length; i++) {
|
||||
if ((i != 0) && (i % 35 == 0)) {
|
||||
if (BIO_write(bp, "\\\n", 2) != 2)
|
||||
goto err;
|
||||
n += 2;
|
||||
}
|
||||
buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
|
||||
buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
|
||||
if (BIO_write(bp, buf, 2) != 2)
|
||||
goto err;
|
||||
n += 2;
|
||||
}
|
||||
}
|
||||
return (n);
|
||||
err:
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int a2i_ASN1_INTEGER(BIO *bp, ASN1_INTEGER *bs, char *buf, int size)
|
||||
{
|
||||
int ret=0;
|
||||
int i,j,k,m,n,again,bufsize;
|
||||
unsigned char *s=NULL,*sp;
|
||||
unsigned char *bufp;
|
||||
int num=0,slen=0,first=1;
|
||||
{
|
||||
int ret = 0;
|
||||
int i, j, k, m, n, again, bufsize;
|
||||
unsigned char *s = NULL, *sp;
|
||||
unsigned char *bufp;
|
||||
int num = 0, slen = 0, first = 1;
|
||||
|
||||
bs->type=V_ASN1_INTEGER;
|
||||
bs->type = V_ASN1_INTEGER;
|
||||
|
||||
bufsize=BIO_gets(bp,buf,size);
|
||||
for (;;)
|
||||
{
|
||||
if (bufsize < 1) goto err_sl;
|
||||
i=bufsize;
|
||||
if (buf[i-1] == '\n') buf[--i]='\0';
|
||||
if (i == 0) goto err_sl;
|
||||
if (buf[i-1] == '\r') buf[--i]='\0';
|
||||
if (i == 0) goto err_sl;
|
||||
again=(buf[i-1] == '\\');
|
||||
bufsize = BIO_gets(bp, buf, size);
|
||||
for (;;) {
|
||||
if (bufsize < 1)
|
||||
goto err_sl;
|
||||
i = bufsize;
|
||||
if (buf[i - 1] == '\n')
|
||||
buf[--i] = '\0';
|
||||
if (i == 0)
|
||||
goto err_sl;
|
||||
if (buf[i - 1] == '\r')
|
||||
buf[--i] = '\0';
|
||||
if (i == 0)
|
||||
goto err_sl;
|
||||
again = (buf[i - 1] == '\\');
|
||||
|
||||
for (j=0; j<i; j++)
|
||||
{
|
||||
for (j = 0; j < i; j++) {
|
||||
#ifndef CHARSET_EBCDIC
|
||||
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
|
||||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
|
||||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
|
||||
if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
|
||||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
|
||||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
|
||||
#else
|
||||
/* This #ifdef is not strictly necessary, since
|
||||
* the characters A...F a...f 0...9 are contiguous
|
||||
* (yes, even in EBCDIC - but not the whole alphabet).
|
||||
* Nevertheless, isxdigit() is faster.
|
||||
*/
|
||||
if (!isxdigit(buf[j]))
|
||||
/*
|
||||
* This #ifdef is not strictly necessary, since the characters
|
||||
* A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but
|
||||
* not the whole alphabet). Nevertheless, isxdigit() is faster.
|
||||
*/
|
||||
if (!isxdigit(buf[j]))
|
||||
#endif
|
||||
{
|
||||
i=j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[i]='\0';
|
||||
/* We have now cleared all the crap off the end of the
|
||||
* line */
|
||||
if (i < 2) goto err_sl;
|
||||
|
||||
bufp=(unsigned char *)buf;
|
||||
if (first)
|
||||
{
|
||||
first=0;
|
||||
if ((bufp[0] == '0') && (buf[1] == '0'))
|
||||
{
|
||||
bufp+=2;
|
||||
i-=2;
|
||||
}
|
||||
}
|
||||
k=0;
|
||||
i-=again;
|
||||
if (i%2 != 0)
|
||||
{
|
||||
ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_ODD_NUMBER_OF_CHARS);
|
||||
goto err;
|
||||
}
|
||||
i/=2;
|
||||
if (num+i > slen)
|
||||
{
|
||||
if (s == NULL)
|
||||
sp=(unsigned char *)OPENSSL_malloc(
|
||||
(unsigned int)num+i*2);
|
||||
else
|
||||
sp=OPENSSL_realloc_clean(s,slen,num+i*2);
|
||||
if (sp == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_A2I_ASN1_INTEGER,ERR_R_MALLOC_FAILURE);
|
||||
if (s != NULL) OPENSSL_free(s);
|
||||
goto err;
|
||||
}
|
||||
s=sp;
|
||||
slen=num+i*2;
|
||||
}
|
||||
for (j=0; j<i; j++,k+=2)
|
||||
{
|
||||
for (n=0; n<2; n++)
|
||||
{
|
||||
m=bufp[k+n];
|
||||
if ((m >= '0') && (m <= '9'))
|
||||
m-='0';
|
||||
else if ((m >= 'a') && (m <= 'f'))
|
||||
m=m-'a'+10;
|
||||
else if ((m >= 'A') && (m <= 'F'))
|
||||
m=m-'A'+10;
|
||||
else
|
||||
{
|
||||
ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_NON_HEX_CHARACTERS);
|
||||
goto err;
|
||||
}
|
||||
s[num+j]<<=4;
|
||||
s[num+j]|=m;
|
||||
}
|
||||
}
|
||||
num+=i;
|
||||
if (again)
|
||||
bufsize=BIO_gets(bp,buf,size);
|
||||
else
|
||||
break;
|
||||
}
|
||||
bs->length=num;
|
||||
bs->data=s;
|
||||
ret=1;
|
||||
err:
|
||||
if (0)
|
||||
{
|
||||
err_sl:
|
||||
ASN1err(ASN1_F_A2I_ASN1_INTEGER,ASN1_R_SHORT_LINE);
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
{
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[i] = '\0';
|
||||
/*
|
||||
* We have now cleared all the crap off the end of the line
|
||||
*/
|
||||
if (i < 2)
|
||||
goto err_sl;
|
||||
|
||||
bufp = (unsigned char *)buf;
|
||||
if (first) {
|
||||
first = 0;
|
||||
if ((bufp[0] == '0') && (buf[1] == '0')) {
|
||||
bufp += 2;
|
||||
i -= 2;
|
||||
}
|
||||
}
|
||||
k = 0;
|
||||
i -= again;
|
||||
if (i % 2 != 0) {
|
||||
ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_ODD_NUMBER_OF_CHARS);
|
||||
goto err;
|
||||
}
|
||||
i /= 2;
|
||||
if (num + i > slen) {
|
||||
if (s == NULL)
|
||||
sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
|
||||
i * 2);
|
||||
else
|
||||
sp = OPENSSL_realloc_clean(s, slen, num + i * 2);
|
||||
if (sp == NULL) {
|
||||
ASN1err(ASN1_F_A2I_ASN1_INTEGER, ERR_R_MALLOC_FAILURE);
|
||||
if (s != NULL)
|
||||
OPENSSL_free(s);
|
||||
goto err;
|
||||
}
|
||||
s = sp;
|
||||
slen = num + i * 2;
|
||||
}
|
||||
for (j = 0; j < i; j++, k += 2) {
|
||||
for (n = 0; n < 2; n++) {
|
||||
m = bufp[k + n];
|
||||
if ((m >= '0') && (m <= '9'))
|
||||
m -= '0';
|
||||
else if ((m >= 'a') && (m <= 'f'))
|
||||
m = m - 'a' + 10;
|
||||
else if ((m >= 'A') && (m <= 'F'))
|
||||
m = m - 'A' + 10;
|
||||
else {
|
||||
ASN1err(ASN1_F_A2I_ASN1_INTEGER,
|
||||
ASN1_R_NON_HEX_CHARACTERS);
|
||||
goto err;
|
||||
}
|
||||
s[num + j] <<= 4;
|
||||
s[num + j] |= m;
|
||||
}
|
||||
}
|
||||
num += i;
|
||||
if (again)
|
||||
bufsize = BIO_gets(bp, buf, size);
|
||||
else
|
||||
break;
|
||||
}
|
||||
bs->length = num;
|
||||
bs->data = s;
|
||||
ret = 1;
|
||||
err:
|
||||
if (0) {
|
||||
err_sl:
|
||||
ASN1err(ASN1_F_A2I_ASN1_INTEGER, ASN1_R_SHORT_LINE);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,151 +62,148 @@
|
||||
#include <openssl/asn1.h>
|
||||
|
||||
int i2a_ASN1_STRING(BIO *bp, ASN1_STRING *a, int type)
|
||||
{
|
||||
int i,n=0;
|
||||
static const char *h="0123456789ABCDEF";
|
||||
char buf[2];
|
||||
{
|
||||
int i, n = 0;
|
||||
static const char *h = "0123456789ABCDEF";
|
||||
char buf[2];
|
||||
|
||||
if (a == NULL) return(0);
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
|
||||
if (a->length == 0)
|
||||
{
|
||||
if (BIO_write(bp,"0",1) != 1) goto err;
|
||||
n=1;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i<a->length; i++)
|
||||
{
|
||||
if ((i != 0) && (i%35 == 0))
|
||||
{
|
||||
if (BIO_write(bp,"\\\n",2) != 2) goto err;
|
||||
n+=2;
|
||||
}
|
||||
buf[0]=h[((unsigned char)a->data[i]>>4)&0x0f];
|
||||
buf[1]=h[((unsigned char)a->data[i] )&0x0f];
|
||||
if (BIO_write(bp,buf,2) != 2) goto err;
|
||||
n+=2;
|
||||
}
|
||||
}
|
||||
return(n);
|
||||
err:
|
||||
return(-1);
|
||||
}
|
||||
if (a->length == 0) {
|
||||
if (BIO_write(bp, "0", 1) != 1)
|
||||
goto err;
|
||||
n = 1;
|
||||
} else {
|
||||
for (i = 0; i < a->length; i++) {
|
||||
if ((i != 0) && (i % 35 == 0)) {
|
||||
if (BIO_write(bp, "\\\n", 2) != 2)
|
||||
goto err;
|
||||
n += 2;
|
||||
}
|
||||
buf[0] = h[((unsigned char)a->data[i] >> 4) & 0x0f];
|
||||
buf[1] = h[((unsigned char)a->data[i]) & 0x0f];
|
||||
if (BIO_write(bp, buf, 2) != 2)
|
||||
goto err;
|
||||
n += 2;
|
||||
}
|
||||
}
|
||||
return (n);
|
||||
err:
|
||||
return (-1);
|
||||
}
|
||||
|
||||
int a2i_ASN1_STRING(BIO *bp, ASN1_STRING *bs, char *buf, int size)
|
||||
{
|
||||
int ret=0;
|
||||
int i,j,k,m,n,again,bufsize;
|
||||
unsigned char *s=NULL,*sp;
|
||||
unsigned char *bufp;
|
||||
int num=0,slen=0,first=1;
|
||||
{
|
||||
int ret = 0;
|
||||
int i, j, k, m, n, again, bufsize;
|
||||
unsigned char *s = NULL, *sp;
|
||||
unsigned char *bufp;
|
||||
int num = 0, slen = 0, first = 1;
|
||||
|
||||
bufsize=BIO_gets(bp,buf,size);
|
||||
for (;;)
|
||||
{
|
||||
if (bufsize < 1)
|
||||
{
|
||||
if (first)
|
||||
break;
|
||||
else
|
||||
goto err_sl;
|
||||
}
|
||||
first=0;
|
||||
bufsize = BIO_gets(bp, buf, size);
|
||||
for (;;) {
|
||||
if (bufsize < 1) {
|
||||
if (first)
|
||||
break;
|
||||
else
|
||||
goto err_sl;
|
||||
}
|
||||
first = 0;
|
||||
|
||||
i=bufsize;
|
||||
if (buf[i-1] == '\n') buf[--i]='\0';
|
||||
if (i == 0) goto err_sl;
|
||||
if (buf[i-1] == '\r') buf[--i]='\0';
|
||||
if (i == 0) goto err_sl;
|
||||
again=(buf[i-1] == '\\');
|
||||
i = bufsize;
|
||||
if (buf[i - 1] == '\n')
|
||||
buf[--i] = '\0';
|
||||
if (i == 0)
|
||||
goto err_sl;
|
||||
if (buf[i - 1] == '\r')
|
||||
buf[--i] = '\0';
|
||||
if (i == 0)
|
||||
goto err_sl;
|
||||
again = (buf[i - 1] == '\\');
|
||||
|
||||
for (j=i-1; j>0; j--)
|
||||
{
|
||||
for (j = i - 1; j > 0; j--) {
|
||||
#ifndef CHARSET_EBCDIC
|
||||
if (!( ((buf[j] >= '0') && (buf[j] <= '9')) ||
|
||||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
|
||||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
|
||||
if (!(((buf[j] >= '0') && (buf[j] <= '9')) ||
|
||||
((buf[j] >= 'a') && (buf[j] <= 'f')) ||
|
||||
((buf[j] >= 'A') && (buf[j] <= 'F'))))
|
||||
#else
|
||||
/* This #ifdef is not strictly necessary, since
|
||||
* the characters A...F a...f 0...9 are contiguous
|
||||
* (yes, even in EBCDIC - but not the whole alphabet).
|
||||
* Nevertheless, isxdigit() is faster.
|
||||
*/
|
||||
if (!isxdigit(buf[j]))
|
||||
/*
|
||||
* This #ifdef is not strictly necessary, since the characters
|
||||
* A...F a...f 0...9 are contiguous (yes, even in EBCDIC - but
|
||||
* not the whole alphabet). Nevertheless, isxdigit() is faster.
|
||||
*/
|
||||
if (!isxdigit(buf[j]))
|
||||
#endif
|
||||
{
|
||||
i=j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[i]='\0';
|
||||
/* We have now cleared all the crap off the end of the
|
||||
* line */
|
||||
if (i < 2) goto err_sl;
|
||||
{
|
||||
i = j;
|
||||
break;
|
||||
}
|
||||
}
|
||||
buf[i] = '\0';
|
||||
/*
|
||||
* We have now cleared all the crap off the end of the line
|
||||
*/
|
||||
if (i < 2)
|
||||
goto err_sl;
|
||||
|
||||
bufp=(unsigned char *)buf;
|
||||
|
||||
k=0;
|
||||
i-=again;
|
||||
if (i%2 != 0)
|
||||
{
|
||||
ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_ODD_NUMBER_OF_CHARS);
|
||||
goto err;
|
||||
}
|
||||
i/=2;
|
||||
if (num+i > slen)
|
||||
{
|
||||
if (s == NULL)
|
||||
sp=(unsigned char *)OPENSSL_malloc(
|
||||
(unsigned int)num+i*2);
|
||||
else
|
||||
sp=(unsigned char *)OPENSSL_realloc(s,
|
||||
(unsigned int)num+i*2);
|
||||
if (sp == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_A2I_ASN1_STRING,ERR_R_MALLOC_FAILURE);
|
||||
if (s != NULL) OPENSSL_free(s);
|
||||
goto err;
|
||||
}
|
||||
s=sp;
|
||||
slen=num+i*2;
|
||||
}
|
||||
for (j=0; j<i; j++,k+=2)
|
||||
{
|
||||
for (n=0; n<2; n++)
|
||||
{
|
||||
m=bufp[k+n];
|
||||
if ((m >= '0') && (m <= '9'))
|
||||
m-='0';
|
||||
else if ((m >= 'a') && (m <= 'f'))
|
||||
m=m-'a'+10;
|
||||
else if ((m >= 'A') && (m <= 'F'))
|
||||
m=m-'A'+10;
|
||||
else
|
||||
{
|
||||
ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_NON_HEX_CHARACTERS);
|
||||
goto err;
|
||||
}
|
||||
s[num+j]<<=4;
|
||||
s[num+j]|=m;
|
||||
}
|
||||
}
|
||||
num+=i;
|
||||
if (again)
|
||||
bufsize=BIO_gets(bp,buf,size);
|
||||
else
|
||||
break;
|
||||
}
|
||||
bs->length=num;
|
||||
bs->data=s;
|
||||
ret=1;
|
||||
err:
|
||||
if (0)
|
||||
{
|
||||
err_sl:
|
||||
ASN1err(ASN1_F_A2I_ASN1_STRING,ASN1_R_SHORT_LINE);
|
||||
}
|
||||
return(ret);
|
||||
}
|
||||
bufp = (unsigned char *)buf;
|
||||
|
||||
k = 0;
|
||||
i -= again;
|
||||
if (i % 2 != 0) {
|
||||
ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_ODD_NUMBER_OF_CHARS);
|
||||
goto err;
|
||||
}
|
||||
i /= 2;
|
||||
if (num + i > slen) {
|
||||
if (s == NULL)
|
||||
sp = (unsigned char *)OPENSSL_malloc((unsigned int)num +
|
||||
i * 2);
|
||||
else
|
||||
sp = (unsigned char *)OPENSSL_realloc(s,
|
||||
(unsigned int)num +
|
||||
i * 2);
|
||||
if (sp == NULL) {
|
||||
ASN1err(ASN1_F_A2I_ASN1_STRING, ERR_R_MALLOC_FAILURE);
|
||||
if (s != NULL)
|
||||
OPENSSL_free(s);
|
||||
goto err;
|
||||
}
|
||||
s = sp;
|
||||
slen = num + i * 2;
|
||||
}
|
||||
for (j = 0; j < i; j++, k += 2) {
|
||||
for (n = 0; n < 2; n++) {
|
||||
m = bufp[k + n];
|
||||
if ((m >= '0') && (m <= '9'))
|
||||
m -= '0';
|
||||
else if ((m >= 'a') && (m <= 'f'))
|
||||
m = m - 'a' + 10;
|
||||
else if ((m >= 'A') && (m <= 'F'))
|
||||
m = m - 'A' + 10;
|
||||
else {
|
||||
ASN1err(ASN1_F_A2I_ASN1_STRING,
|
||||
ASN1_R_NON_HEX_CHARACTERS);
|
||||
goto err;
|
||||
}
|
||||
s[num + j] <<= 4;
|
||||
s[num + j] |= m;
|
||||
}
|
||||
}
|
||||
num += i;
|
||||
if (again)
|
||||
bufsize = BIO_gets(bp, buf, size);
|
||||
else
|
||||
break;
|
||||
}
|
||||
bs->length = num;
|
||||
bs->data = s;
|
||||
ret = 1;
|
||||
err:
|
||||
if (0) {
|
||||
err_sl:
|
||||
ASN1err(ASN1_F_A2I_ASN1_STRING, ASN1_R_SHORT_LINE);
|
||||
}
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -63,18 +63,16 @@
|
||||
#include "asn1_locl.h"
|
||||
|
||||
int i2d_PrivateKey(EVP_PKEY *a, unsigned char **pp)
|
||||
{
|
||||
if (a->ameth && a->ameth->old_priv_encode)
|
||||
{
|
||||
return a->ameth->old_priv_encode(a, pp);
|
||||
}
|
||||
if (a->ameth && a->ameth->priv_encode) {
|
||||
PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
|
||||
int ret = i2d_PKCS8_PRIV_KEY_INFO(p8,pp);
|
||||
PKCS8_PRIV_KEY_INFO_free(p8);
|
||||
return ret;
|
||||
}
|
||||
ASN1err(ASN1_F_I2D_PRIVATEKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
|
||||
return(-1);
|
||||
}
|
||||
|
||||
{
|
||||
if (a->ameth && a->ameth->old_priv_encode) {
|
||||
return a->ameth->old_priv_encode(a, pp);
|
||||
}
|
||||
if (a->ameth && a->ameth->priv_encode) {
|
||||
PKCS8_PRIV_KEY_INFO *p8 = EVP_PKEY2PKCS8(a);
|
||||
int ret = i2d_PKCS8_PRIV_KEY_INFO(p8, pp);
|
||||
PKCS8_PRIV_KEY_INFO_free(p8);
|
||||
return ret;
|
||||
}
|
||||
ASN1err(ASN1_F_I2D_PRIVATEKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
|
||||
return (-1);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,34 +62,32 @@
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/objects.h>
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
#include <openssl/rsa.h>
|
||||
# include <openssl/rsa.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
#include <openssl/dsa.h>
|
||||
# include <openssl/dsa.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
#include <openssl/ec.h>
|
||||
# include <openssl/ec.h>
|
||||
#endif
|
||||
|
||||
int i2d_PublicKey(EVP_PKEY *a, unsigned char **pp)
|
||||
{
|
||||
switch (a->type)
|
||||
{
|
||||
{
|
||||
switch (a->type) {
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
case EVP_PKEY_RSA:
|
||||
return(i2d_RSAPublicKey(a->pkey.rsa,pp));
|
||||
case EVP_PKEY_RSA:
|
||||
return (i2d_RSAPublicKey(a->pkey.rsa, pp));
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
case EVP_PKEY_DSA:
|
||||
return(i2d_DSAPublicKey(a->pkey.dsa,pp));
|
||||
case EVP_PKEY_DSA:
|
||||
return (i2d_DSAPublicKey(a->pkey.dsa, pp));
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
case EVP_PKEY_EC:
|
||||
return(i2o_ECPublicKey(a->pkey.ec, pp));
|
||||
case EVP_PKEY_EC:
|
||||
return (i2o_ECPublicKey(a->pkey.ec, pp));
|
||||
#endif
|
||||
default:
|
||||
ASN1err(ASN1_F_I2D_PUBLICKEY,ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
|
||||
return(-1);
|
||||
}
|
||||
}
|
||||
|
||||
default:
|
||||
ASN1err(ASN1_F_I2D_PUBLICKEY, ASN1_R_UNSUPPORTED_PUBLIC_KEY_TYPE);
|
||||
return (-1);
|
||||
}
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -59,37 +59,34 @@
|
||||
#include <stdio.h>
|
||||
#include "cryptlib.h"
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
#include <openssl/rsa.h>
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/asn1_mac.h>
|
||||
#include <openssl/evp.h>
|
||||
#include <openssl/x509.h>
|
||||
# include <openssl/rsa.h>
|
||||
# include <openssl/objects.h>
|
||||
# include <openssl/asn1t.h>
|
||||
# include <openssl/asn1_mac.h>
|
||||
# include <openssl/evp.h>
|
||||
# include <openssl/x509.h>
|
||||
|
||||
# ifndef OPENSSL_NO_RC4
|
||||
|
||||
#ifndef OPENSSL_NO_RC4
|
||||
typedef struct netscape_pkey_st {
|
||||
long version;
|
||||
X509_ALGOR *algor;
|
||||
ASN1_OCTET_STRING *private_key;
|
||||
} NETSCAPE_PKEY;
|
||||
|
||||
typedef struct netscape_pkey_st
|
||||
{
|
||||
long version;
|
||||
X509_ALGOR *algor;
|
||||
ASN1_OCTET_STRING *private_key;
|
||||
} NETSCAPE_PKEY;
|
||||
|
||||
typedef struct netscape_encrypted_pkey_st
|
||||
{
|
||||
ASN1_OCTET_STRING *os;
|
||||
/* This is the same structure as DigestInfo so use it:
|
||||
* although this isn't really anything to do with
|
||||
* digests.
|
||||
*/
|
||||
X509_SIG *enckey;
|
||||
} NETSCAPE_ENCRYPTED_PKEY;
|
||||
typedef struct netscape_encrypted_pkey_st {
|
||||
ASN1_OCTET_STRING *os;
|
||||
/*
|
||||
* This is the same structure as DigestInfo so use it: although this
|
||||
* isn't really anything to do with digests.
|
||||
*/
|
||||
X509_SIG *enckey;
|
||||
} NETSCAPE_ENCRYPTED_PKEY;
|
||||
|
||||
|
||||
ASN1_BROKEN_SEQUENCE(NETSCAPE_ENCRYPTED_PKEY) = {
|
||||
ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING),
|
||||
ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG)
|
||||
ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, os, ASN1_OCTET_STRING),
|
||||
ASN1_SIMPLE(NETSCAPE_ENCRYPTED_PKEY, enckey, X509_SIG)
|
||||
} ASN1_BROKEN_SEQUENCE_END(NETSCAPE_ENCRYPTED_PKEY)
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
|
||||
@ -97,9 +94,9 @@ DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY,NETSCAPE_ENCRYPTED_P
|
||||
IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_ENCRYPTED_PKEY)
|
||||
|
||||
ASN1_SEQUENCE(NETSCAPE_PKEY) = {
|
||||
ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG),
|
||||
ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR),
|
||||
ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING)
|
||||
ASN1_SIMPLE(NETSCAPE_PKEY, version, LONG),
|
||||
ASN1_SIMPLE(NETSCAPE_PKEY, algor, X509_ALGOR),
|
||||
ASN1_SIMPLE(NETSCAPE_PKEY, private_key, ASN1_OCTET_STRING)
|
||||
} ASN1_SEQUENCE_END(NETSCAPE_PKEY)
|
||||
|
||||
DECLARE_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
|
||||
@ -107,247 +104,242 @@ DECLARE_ASN1_ENCODE_FUNCTIONS_const(NETSCAPE_PKEY,NETSCAPE_PKEY)
|
||||
IMPLEMENT_ASN1_FUNCTIONS_const(NETSCAPE_PKEY)
|
||||
|
||||
static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
|
||||
int (*cb)(char *buf, int len, const char *prompt,
|
||||
int verify),
|
||||
int sgckey);
|
||||
int (*cb) (char *buf, int len, const char *prompt,
|
||||
int verify), int sgckey);
|
||||
|
||||
int i2d_Netscape_RSA(const RSA *a, unsigned char **pp,
|
||||
int (*cb)(char *buf, int len, const char *prompt,
|
||||
int verify))
|
||||
int (*cb) (char *buf, int len, const char *prompt,
|
||||
int verify))
|
||||
{
|
||||
return i2d_RSA_NET(a, pp, cb, 0);
|
||||
return i2d_RSA_NET(a, pp, cb, 0);
|
||||
}
|
||||
|
||||
int i2d_RSA_NET(const RSA *a, unsigned char **pp,
|
||||
int (*cb)(char *buf, int len, const char *prompt, int verify),
|
||||
int sgckey)
|
||||
{
|
||||
int i, j, ret = 0;
|
||||
int rsalen, pkeylen, olen;
|
||||
NETSCAPE_PKEY *pkey = NULL;
|
||||
NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
|
||||
unsigned char buf[256],*zz;
|
||||
unsigned char key[EVP_MAX_KEY_LENGTH];
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
int (*cb) (char *buf, int len, const char *prompt,
|
||||
int verify), int sgckey)
|
||||
{
|
||||
int i, j, ret = 0;
|
||||
int rsalen, pkeylen, olen;
|
||||
NETSCAPE_PKEY *pkey = NULL;
|
||||
NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
|
||||
unsigned char buf[256], *zz;
|
||||
unsigned char key[EVP_MAX_KEY_LENGTH];
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
|
||||
if (a == NULL) return(0);
|
||||
if (a == NULL)
|
||||
return (0);
|
||||
|
||||
if ((pkey=NETSCAPE_PKEY_new()) == NULL) goto err;
|
||||
if ((enckey=NETSCAPE_ENCRYPTED_PKEY_new()) == NULL) goto err;
|
||||
pkey->version = 0;
|
||||
if ((pkey = NETSCAPE_PKEY_new()) == NULL)
|
||||
goto err;
|
||||
if ((enckey = NETSCAPE_ENCRYPTED_PKEY_new()) == NULL)
|
||||
goto err;
|
||||
pkey->version = 0;
|
||||
|
||||
pkey->algor->algorithm=OBJ_nid2obj(NID_rsaEncryption);
|
||||
if ((pkey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err;
|
||||
pkey->algor->parameter->type=V_ASN1_NULL;
|
||||
pkey->algor->algorithm = OBJ_nid2obj(NID_rsaEncryption);
|
||||
if ((pkey->algor->parameter = ASN1_TYPE_new()) == NULL)
|
||||
goto err;
|
||||
pkey->algor->parameter->type = V_ASN1_NULL;
|
||||
|
||||
rsalen = i2d_RSAPrivateKey(a, NULL);
|
||||
rsalen = i2d_RSAPrivateKey(a, NULL);
|
||||
|
||||
/* Fake some octet strings just for the initial length
|
||||
* calculation.
|
||||
*/
|
||||
/*
|
||||
* Fake some octet strings just for the initial length calculation.
|
||||
*/
|
||||
|
||||
pkey->private_key->length=rsalen;
|
||||
pkey->private_key->length = rsalen;
|
||||
|
||||
pkeylen=i2d_NETSCAPE_PKEY(pkey,NULL);
|
||||
pkeylen = i2d_NETSCAPE_PKEY(pkey, NULL);
|
||||
|
||||
enckey->enckey->digest->length = pkeylen;
|
||||
enckey->enckey->digest->length = pkeylen;
|
||||
|
||||
enckey->os->length = 11; /* "private-key" */
|
||||
enckey->os->length = 11; /* "private-key" */
|
||||
|
||||
enckey->enckey->algor->algorithm=OBJ_nid2obj(NID_rc4);
|
||||
if ((enckey->enckey->algor->parameter=ASN1_TYPE_new()) == NULL) goto err;
|
||||
enckey->enckey->algor->parameter->type=V_ASN1_NULL;
|
||||
enckey->enckey->algor->algorithm = OBJ_nid2obj(NID_rc4);
|
||||
if ((enckey->enckey->algor->parameter = ASN1_TYPE_new()) == NULL)
|
||||
goto err;
|
||||
enckey->enckey->algor->parameter->type = V_ASN1_NULL;
|
||||
|
||||
if (pp == NULL)
|
||||
{
|
||||
olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL);
|
||||
NETSCAPE_PKEY_free(pkey);
|
||||
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
|
||||
return olen;
|
||||
}
|
||||
if (pp == NULL) {
|
||||
olen = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, NULL);
|
||||
NETSCAPE_PKEY_free(pkey);
|
||||
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
|
||||
return olen;
|
||||
}
|
||||
|
||||
/* Since its RC4 encrypted length is actual length */
|
||||
if ((zz = (unsigned char *)OPENSSL_malloc(rsalen)) == NULL) {
|
||||
ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
/* Since its RC4 encrypted length is actual length */
|
||||
if ((zz=(unsigned char *)OPENSSL_malloc(rsalen)) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
pkey->private_key->data = zz;
|
||||
/* Write out private key encoding */
|
||||
i2d_RSAPrivateKey(a, &zz);
|
||||
|
||||
pkey->private_key->data = zz;
|
||||
/* Write out private key encoding */
|
||||
i2d_RSAPrivateKey(a,&zz);
|
||||
if ((zz = OPENSSL_malloc(pkeylen)) == NULL) {
|
||||
ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
if ((zz=OPENSSL_malloc(pkeylen)) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!ASN1_STRING_set(enckey->os, "private-key", -1)) {
|
||||
ASN1err(ASN1_F_I2D_RSA_NET, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
enckey->enckey->digest->data = zz;
|
||||
i2d_NETSCAPE_PKEY(pkey, &zz);
|
||||
|
||||
if (!ASN1_STRING_set(enckey->os, "private-key", -1))
|
||||
{
|
||||
ASN1err(ASN1_F_I2D_RSA_NET,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
enckey->enckey->digest->data = zz;
|
||||
i2d_NETSCAPE_PKEY(pkey,&zz);
|
||||
/* Wipe the private key encoding */
|
||||
OPENSSL_cleanse(pkey->private_key->data, rsalen);
|
||||
|
||||
/* Wipe the private key encoding */
|
||||
OPENSSL_cleanse(pkey->private_key->data, rsalen);
|
||||
|
||||
if (cb == NULL)
|
||||
cb=EVP_read_pw_string;
|
||||
i=cb((char *)buf,256,"Enter Private Key password:",1);
|
||||
if (i != 0)
|
||||
{
|
||||
ASN1err(ASN1_F_I2D_RSA_NET,ASN1_R_BAD_PASSWORD_READ);
|
||||
goto err;
|
||||
}
|
||||
i = strlen((char *)buf);
|
||||
/* If the key is used for SGC the algorithm is modified a little. */
|
||||
if(sgckey) {
|
||||
if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
|
||||
goto err;
|
||||
memcpy(buf + 16, "SGCKEYSALT", 10);
|
||||
i = 26;
|
||||
}
|
||||
if (cb == NULL)
|
||||
cb = EVP_read_pw_string;
|
||||
i = cb((char *)buf, 256, "Enter Private Key password:", 1);
|
||||
if (i != 0) {
|
||||
ASN1err(ASN1_F_I2D_RSA_NET, ASN1_R_BAD_PASSWORD_READ);
|
||||
goto err;
|
||||
}
|
||||
i = strlen((char *)buf);
|
||||
/* If the key is used for SGC the algorithm is modified a little. */
|
||||
if (sgckey) {
|
||||
if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
|
||||
goto err;
|
||||
memcpy(buf + 16, "SGCKEYSALT", 10);
|
||||
i = 26;
|
||||
}
|
||||
|
||||
if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
|
||||
goto err;
|
||||
OPENSSL_cleanse(buf,256);
|
||||
if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL))
|
||||
goto err;
|
||||
OPENSSL_cleanse(buf, 256);
|
||||
|
||||
/* Encrypt private key in place */
|
||||
zz = enckey->enckey->digest->data;
|
||||
if (!EVP_EncryptInit_ex(&ctx,EVP_rc4(),NULL,key,NULL))
|
||||
goto err;
|
||||
if (!EVP_EncryptUpdate(&ctx,zz,&i,zz,pkeylen))
|
||||
goto err;
|
||||
if (!EVP_EncryptFinal_ex(&ctx,zz + i,&j))
|
||||
goto err;
|
||||
|
||||
ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
|
||||
err:
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
|
||||
NETSCAPE_PKEY_free(pkey);
|
||||
return(ret);
|
||||
}
|
||||
/* Encrypt private key in place */
|
||||
zz = enckey->enckey->digest->data;
|
||||
if (!EVP_EncryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
|
||||
goto err;
|
||||
if (!EVP_EncryptUpdate(&ctx, zz, &i, zz, pkeylen))
|
||||
goto err;
|
||||
if (!EVP_EncryptFinal_ex(&ctx, zz + i, &j))
|
||||
goto err;
|
||||
|
||||
ret = i2d_NETSCAPE_ENCRYPTED_PKEY(enckey, pp);
|
||||
err:
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
|
||||
NETSCAPE_PKEY_free(pkey);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
RSA *d2i_Netscape_RSA(RSA **a, const unsigned char **pp, long length,
|
||||
int (*cb)(char *buf, int len, const char *prompt,
|
||||
int verify))
|
||||
int (*cb) (char *buf, int len, const char *prompt,
|
||||
int verify))
|
||||
{
|
||||
return d2i_RSA_NET(a, pp, length, cb, 0);
|
||||
return d2i_RSA_NET(a, pp, length, cb, 0);
|
||||
}
|
||||
|
||||
RSA *d2i_RSA_NET(RSA **a, const unsigned char **pp, long length,
|
||||
int (*cb)(char *buf, int len, const char *prompt, int verify),
|
||||
int sgckey)
|
||||
{
|
||||
RSA *ret=NULL;
|
||||
const unsigned char *p;
|
||||
NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
|
||||
int (*cb) (char *buf, int len, const char *prompt,
|
||||
int verify), int sgckey)
|
||||
{
|
||||
RSA *ret = NULL;
|
||||
const unsigned char *p;
|
||||
NETSCAPE_ENCRYPTED_PKEY *enckey = NULL;
|
||||
|
||||
p = *pp;
|
||||
p = *pp;
|
||||
|
||||
enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length);
|
||||
if(!enckey) {
|
||||
ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_DECODING_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
enckey = d2i_NETSCAPE_ENCRYPTED_PKEY(NULL, &p, length);
|
||||
if (!enckey) {
|
||||
ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_DECODING_ERROR);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if ((enckey->os->length != 11) || (strncmp("private-key",
|
||||
(char *)enckey->os->data,11) != 0))
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_PRIVATE_KEY_HEADER_MISSING);
|
||||
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
|
||||
return NULL;
|
||||
}
|
||||
if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_RSA_NET,ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
|
||||
goto err;
|
||||
}
|
||||
if (cb == NULL)
|
||||
cb=EVP_read_pw_string;
|
||||
if ((ret=d2i_RSA_NET_2(a, enckey->enckey->digest,cb, sgckey)) == NULL) goto err;
|
||||
if ((enckey->os->length != 11) || (strncmp("private-key",
|
||||
(char *)enckey->os->data,
|
||||
11) != 0)) {
|
||||
ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_PRIVATE_KEY_HEADER_MISSING);
|
||||
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
|
||||
return NULL;
|
||||
}
|
||||
if (OBJ_obj2nid(enckey->enckey->algor->algorithm) != NID_rc4) {
|
||||
ASN1err(ASN1_F_D2I_RSA_NET, ASN1_R_UNSUPPORTED_ENCRYPTION_ALGORITHM);
|
||||
goto err;
|
||||
}
|
||||
if (cb == NULL)
|
||||
cb = EVP_read_pw_string;
|
||||
if ((ret = d2i_RSA_NET_2(a, enckey->enckey->digest, cb, sgckey)) == NULL)
|
||||
goto err;
|
||||
|
||||
*pp = p;
|
||||
*pp = p;
|
||||
|
||||
err:
|
||||
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
|
||||
return ret;
|
||||
err:
|
||||
NETSCAPE_ENCRYPTED_PKEY_free(enckey);
|
||||
return ret;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static RSA *d2i_RSA_NET_2(RSA **a, ASN1_OCTET_STRING *os,
|
||||
int (*cb)(char *buf, int len, const char *prompt,
|
||||
int verify), int sgckey)
|
||||
{
|
||||
NETSCAPE_PKEY *pkey=NULL;
|
||||
RSA *ret=NULL;
|
||||
int i,j;
|
||||
unsigned char buf[256];
|
||||
const unsigned char *zz;
|
||||
unsigned char key[EVP_MAX_KEY_LENGTH];
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
int (*cb) (char *buf, int len, const char *prompt,
|
||||
int verify), int sgckey)
|
||||
{
|
||||
NETSCAPE_PKEY *pkey = NULL;
|
||||
RSA *ret = NULL;
|
||||
int i, j;
|
||||
unsigned char buf[256];
|
||||
const unsigned char *zz;
|
||||
unsigned char key[EVP_MAX_KEY_LENGTH];
|
||||
EVP_CIPHER_CTX ctx;
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
|
||||
i=cb((char *)buf,256,"Enter Private Key password:",0);
|
||||
if (i != 0)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_BAD_PASSWORD_READ);
|
||||
goto err;
|
||||
}
|
||||
i = cb((char *)buf, 256, "Enter Private Key password:", 0);
|
||||
if (i != 0) {
|
||||
ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_BAD_PASSWORD_READ);
|
||||
goto err;
|
||||
}
|
||||
|
||||
i = strlen((char *)buf);
|
||||
if(sgckey){
|
||||
if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
|
||||
goto err;
|
||||
memcpy(buf + 16, "SGCKEYSALT", 10);
|
||||
i = 26;
|
||||
}
|
||||
|
||||
if (!EVP_BytesToKey(EVP_rc4(),EVP_md5(),NULL,buf,i,1,key,NULL))
|
||||
goto err;
|
||||
OPENSSL_cleanse(buf,256);
|
||||
i = strlen((char *)buf);
|
||||
if (sgckey) {
|
||||
if (!EVP_Digest(buf, i, buf, NULL, EVP_md5(), NULL))
|
||||
goto err;
|
||||
memcpy(buf + 16, "SGCKEYSALT", 10);
|
||||
i = 26;
|
||||
}
|
||||
|
||||
if (!EVP_DecryptInit_ex(&ctx,EVP_rc4(),NULL, key,NULL))
|
||||
goto err;
|
||||
if (!EVP_DecryptUpdate(&ctx,os->data,&i,os->data,os->length))
|
||||
goto err;
|
||||
if (!EVP_DecryptFinal_ex(&ctx,&(os->data[i]),&j))
|
||||
goto err;
|
||||
os->length=i+j;
|
||||
if (!EVP_BytesToKey(EVP_rc4(), EVP_md5(), NULL, buf, i, 1, key, NULL))
|
||||
goto err;
|
||||
OPENSSL_cleanse(buf, 256);
|
||||
|
||||
zz=os->data;
|
||||
if (!EVP_DecryptInit_ex(&ctx, EVP_rc4(), NULL, key, NULL))
|
||||
goto err;
|
||||
if (!EVP_DecryptUpdate(&ctx, os->data, &i, os->data, os->length))
|
||||
goto err;
|
||||
if (!EVP_DecryptFinal_ex(&ctx, &(os->data[i]), &j))
|
||||
goto err;
|
||||
os->length = i + j;
|
||||
|
||||
if ((pkey=d2i_NETSCAPE_PKEY(NULL,&zz,os->length)) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
zz=pkey->private_key->data;
|
||||
if ((ret=d2i_RSAPrivateKey(a,&zz,pkey->private_key->length)) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_D2I_RSA_NET_2,ASN1_R_UNABLE_TO_DECODE_RSA_KEY);
|
||||
goto err;
|
||||
}
|
||||
err:
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
NETSCAPE_PKEY_free(pkey);
|
||||
return(ret);
|
||||
}
|
||||
zz = os->data;
|
||||
|
||||
#endif /* OPENSSL_NO_RC4 */
|
||||
if ((pkey = d2i_NETSCAPE_PKEY(NULL, &zz, os->length)) == NULL) {
|
||||
ASN1err(ASN1_F_D2I_RSA_NET_2,
|
||||
ASN1_R_UNABLE_TO_DECODE_RSA_PRIVATE_KEY);
|
||||
goto err;
|
||||
}
|
||||
|
||||
#else /* !OPENSSL_NO_RSA */
|
||||
zz = pkey->private_key->data;
|
||||
if ((ret = d2i_RSAPrivateKey(a, &zz, pkey->private_key->length)) == NULL) {
|
||||
ASN1err(ASN1_F_D2I_RSA_NET_2, ASN1_R_UNABLE_TO_DECODE_RSA_KEY);
|
||||
goto err;
|
||||
}
|
||||
err:
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
NETSCAPE_PKEY_free(pkey);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
# endif /* OPENSSL_NO_RC4 */
|
||||
|
||||
#else /* !OPENSSL_NO_RSA */
|
||||
|
||||
# if PEDANTIC
|
||||
static void *dummy=&dummy;
|
||||
static void *dummy = &dummy;
|
||||
# endif
|
||||
|
||||
#endif
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* nsseq.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -63,21 +64,21 @@
|
||||
#include <openssl/objects.h>
|
||||
|
||||
static int nsseq_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
void *exarg)
|
||||
void *exarg)
|
||||
{
|
||||
if(operation == ASN1_OP_NEW_POST) {
|
||||
NETSCAPE_CERT_SEQUENCE *nsseq;
|
||||
nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval;
|
||||
nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence);
|
||||
}
|
||||
return 1;
|
||||
if (operation == ASN1_OP_NEW_POST) {
|
||||
NETSCAPE_CERT_SEQUENCE *nsseq;
|
||||
nsseq = (NETSCAPE_CERT_SEQUENCE *)*pval;
|
||||
nsseq->type = OBJ_nid2obj(NID_netscape_cert_sequence);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Netscape certificate sequence structure */
|
||||
|
||||
ASN1_SEQUENCE_cb(NETSCAPE_CERT_SEQUENCE, nsseq_cb) = {
|
||||
ASN1_SIMPLE(NETSCAPE_CERT_SEQUENCE, type, ASN1_OBJECT),
|
||||
ASN1_EXP_SEQUENCE_OF_OPT(NETSCAPE_CERT_SEQUENCE, certs, X509, 0)
|
||||
ASN1_SIMPLE(NETSCAPE_CERT_SEQUENCE, type, ASN1_OBJECT),
|
||||
ASN1_EXP_SEQUENCE_OF_OPT(NETSCAPE_CERT_SEQUENCE, certs, X509, 0)
|
||||
} ASN1_SEQUENCE_END_cb(NETSCAPE_CERT_SEQUENCE, NETSCAPE_CERT_SEQUENCE)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_CERT_SEQUENCE)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* p5_pbe.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -65,84 +66,78 @@
|
||||
/* PKCS#5 password based encryption structure */
|
||||
|
||||
ASN1_SEQUENCE(PBEPARAM) = {
|
||||
ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING),
|
||||
ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER)
|
||||
ASN1_SIMPLE(PBEPARAM, salt, ASN1_OCTET_STRING),
|
||||
ASN1_SIMPLE(PBEPARAM, iter, ASN1_INTEGER)
|
||||
} ASN1_SEQUENCE_END(PBEPARAM)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(PBEPARAM)
|
||||
|
||||
|
||||
/* Set an algorithm identifier for a PKCS#5 PBE algorithm */
|
||||
|
||||
int PKCS5_pbe_set0_algor(X509_ALGOR *algor, int alg, int iter,
|
||||
const unsigned char *salt, int saltlen)
|
||||
{
|
||||
PBEPARAM *pbe=NULL;
|
||||
ASN1_STRING *pbe_str=NULL;
|
||||
unsigned char *sstr;
|
||||
const unsigned char *salt, int saltlen)
|
||||
{
|
||||
PBEPARAM *pbe = NULL;
|
||||
ASN1_STRING *pbe_str = NULL;
|
||||
unsigned char *sstr;
|
||||
|
||||
pbe = PBEPARAM_new();
|
||||
if (!pbe)
|
||||
{
|
||||
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if(iter <= 0)
|
||||
iter = PKCS5_DEFAULT_ITER;
|
||||
if (!ASN1_INTEGER_set(pbe->iter, iter))
|
||||
{
|
||||
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!saltlen)
|
||||
saltlen = PKCS5_SALT_LEN;
|
||||
if (!ASN1_STRING_set(pbe->salt, NULL, saltlen))
|
||||
{
|
||||
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
sstr = ASN1_STRING_data(pbe->salt);
|
||||
if (salt)
|
||||
memcpy(sstr, salt, saltlen);
|
||||
else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
|
||||
goto err;
|
||||
pbe = PBEPARAM_new();
|
||||
if (!pbe) {
|
||||
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (iter <= 0)
|
||||
iter = PKCS5_DEFAULT_ITER;
|
||||
if (!ASN1_INTEGER_set(pbe->iter, iter)) {
|
||||
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!saltlen)
|
||||
saltlen = PKCS5_SALT_LEN;
|
||||
if (!ASN1_STRING_set(pbe->salt, NULL, saltlen)) {
|
||||
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
sstr = ASN1_STRING_data(pbe->salt);
|
||||
if (salt)
|
||||
memcpy(sstr, salt, saltlen);
|
||||
else if (RAND_pseudo_bytes(sstr, saltlen) < 0)
|
||||
goto err;
|
||||
|
||||
if(!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str))
|
||||
{
|
||||
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR,ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
if (!ASN1_item_pack(pbe, ASN1_ITEM_rptr(PBEPARAM), &pbe_str)) {
|
||||
ASN1err(ASN1_F_PKCS5_PBE_SET0_ALGOR, ERR_R_MALLOC_FAILURE);
|
||||
goto err;
|
||||
}
|
||||
|
||||
PBEPARAM_free(pbe);
|
||||
pbe = NULL;
|
||||
PBEPARAM_free(pbe);
|
||||
pbe = NULL;
|
||||
|
||||
if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
|
||||
return 1;
|
||||
if (X509_ALGOR_set0(algor, OBJ_nid2obj(alg), V_ASN1_SEQUENCE, pbe_str))
|
||||
return 1;
|
||||
|
||||
err:
|
||||
if (pbe != NULL)
|
||||
PBEPARAM_free(pbe);
|
||||
if (pbe_str != NULL)
|
||||
ASN1_STRING_free(pbe_str);
|
||||
return 0;
|
||||
}
|
||||
err:
|
||||
if (pbe != NULL)
|
||||
PBEPARAM_free(pbe);
|
||||
if (pbe_str != NULL)
|
||||
ASN1_STRING_free(pbe_str);
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Return an algorithm identifier for a PKCS#5 PBE algorithm */
|
||||
|
||||
X509_ALGOR *PKCS5_pbe_set(int alg, int iter,
|
||||
const unsigned char *salt, int saltlen)
|
||||
{
|
||||
X509_ALGOR *ret;
|
||||
ret = X509_ALGOR_new();
|
||||
if (!ret)
|
||||
{
|
||||
ASN1err(ASN1_F_PKCS5_PBE_SET,ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
const unsigned char *salt, int saltlen)
|
||||
{
|
||||
X509_ALGOR *ret;
|
||||
ret = X509_ALGOR_new();
|
||||
if (!ret) {
|
||||
ASN1err(ASN1_F_PKCS5_PBE_SET, ERR_R_MALLOC_FAILURE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
|
||||
return ret;
|
||||
if (PKCS5_pbe_set0_algor(ret, alg, iter, salt, saltlen))
|
||||
return ret;
|
||||
|
||||
X509_ALGOR_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
X509_ALGOR_free(ret);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* p5_pbev2.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999-2004.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999-2004.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -65,216 +66,215 @@
|
||||
/* PKCS#5 v2.0 password based encryption structures */
|
||||
|
||||
ASN1_SEQUENCE(PBE2PARAM) = {
|
||||
ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR),
|
||||
ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR)
|
||||
ASN1_SIMPLE(PBE2PARAM, keyfunc, X509_ALGOR),
|
||||
ASN1_SIMPLE(PBE2PARAM, encryption, X509_ALGOR)
|
||||
} ASN1_SEQUENCE_END(PBE2PARAM)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(PBE2PARAM)
|
||||
|
||||
ASN1_SEQUENCE(PBKDF2PARAM) = {
|
||||
ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY),
|
||||
ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER),
|
||||
ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER),
|
||||
ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR)
|
||||
ASN1_SIMPLE(PBKDF2PARAM, salt, ASN1_ANY),
|
||||
ASN1_SIMPLE(PBKDF2PARAM, iter, ASN1_INTEGER),
|
||||
ASN1_OPT(PBKDF2PARAM, keylength, ASN1_INTEGER),
|
||||
ASN1_OPT(PBKDF2PARAM, prf, X509_ALGOR)
|
||||
} ASN1_SEQUENCE_END(PBKDF2PARAM)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(PBKDF2PARAM)
|
||||
|
||||
/* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm:
|
||||
* yes I know this is horrible!
|
||||
*
|
||||
* Extended version to allow application supplied PRF NID and IV.
|
||||
/*
|
||||
* Return an algorithm identifier for a PKCS#5 v2.0 PBE algorithm: yes I know
|
||||
* this is horrible! Extended version to allow application supplied PRF NID
|
||||
* and IV.
|
||||
*/
|
||||
|
||||
X509_ALGOR *PKCS5_pbe2_set_iv(const EVP_CIPHER *cipher, int iter,
|
||||
unsigned char *salt, int saltlen,
|
||||
unsigned char *aiv, int prf_nid)
|
||||
unsigned char *salt, int saltlen,
|
||||
unsigned char *aiv, int prf_nid)
|
||||
{
|
||||
X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
|
||||
int alg_nid, keylen;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH];
|
||||
PBE2PARAM *pbe2 = NULL;
|
||||
ASN1_OBJECT *obj;
|
||||
X509_ALGOR *scheme = NULL, *kalg = NULL, *ret = NULL;
|
||||
int alg_nid, keylen;
|
||||
EVP_CIPHER_CTX ctx;
|
||||
unsigned char iv[EVP_MAX_IV_LENGTH];
|
||||
PBE2PARAM *pbe2 = NULL;
|
||||
ASN1_OBJECT *obj;
|
||||
|
||||
alg_nid = EVP_CIPHER_type(cipher);
|
||||
if(alg_nid == NID_undef) {
|
||||
ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
|
||||
ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
|
||||
goto err;
|
||||
}
|
||||
obj = OBJ_nid2obj(alg_nid);
|
||||
alg_nid = EVP_CIPHER_type(cipher);
|
||||
if (alg_nid == NID_undef) {
|
||||
ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
|
||||
ASN1_R_CIPHER_HAS_NO_OBJECT_IDENTIFIER);
|
||||
goto err;
|
||||
}
|
||||
obj = OBJ_nid2obj(alg_nid);
|
||||
|
||||
if(!(pbe2 = PBE2PARAM_new())) goto merr;
|
||||
if (!(pbe2 = PBE2PARAM_new()))
|
||||
goto merr;
|
||||
|
||||
/* Setup the AlgorithmIdentifier for the encryption scheme */
|
||||
scheme = pbe2->encryption;
|
||||
/* Setup the AlgorithmIdentifier for the encryption scheme */
|
||||
scheme = pbe2->encryption;
|
||||
|
||||
scheme->algorithm = obj;
|
||||
if(!(scheme->parameter = ASN1_TYPE_new())) goto merr;
|
||||
scheme->algorithm = obj;
|
||||
if (!(scheme->parameter = ASN1_TYPE_new()))
|
||||
goto merr;
|
||||
|
||||
/* Create random IV */
|
||||
if (EVP_CIPHER_iv_length(cipher))
|
||||
{
|
||||
if (aiv)
|
||||
memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
|
||||
else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
|
||||
goto err;
|
||||
}
|
||||
/* Create random IV */
|
||||
if (EVP_CIPHER_iv_length(cipher)) {
|
||||
if (aiv)
|
||||
memcpy(iv, aiv, EVP_CIPHER_iv_length(cipher));
|
||||
else if (RAND_pseudo_bytes(iv, EVP_CIPHER_iv_length(cipher)) < 0)
|
||||
goto err;
|
||||
}
|
||||
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
EVP_CIPHER_CTX_init(&ctx);
|
||||
|
||||
/* Dummy cipherinit to just setup the IV, and PRF */
|
||||
if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
|
||||
goto err;
|
||||
if(EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
|
||||
ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,
|
||||
ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
goto err;
|
||||
}
|
||||
/* If prf NID unspecified see if cipher has a preference.
|
||||
* An error is OK here: just means use default PRF.
|
||||
*/
|
||||
if ((prf_nid == -1) &&
|
||||
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0)
|
||||
{
|
||||
ERR_clear_error();
|
||||
prf_nid = NID_hmacWithSHA1;
|
||||
}
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
/* Dummy cipherinit to just setup the IV, and PRF */
|
||||
if (!EVP_CipherInit_ex(&ctx, cipher, NULL, NULL, iv, 0))
|
||||
goto err;
|
||||
if (EVP_CIPHER_param_to_asn1(&ctx, scheme->parameter) < 0) {
|
||||
ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ASN1_R_ERROR_SETTING_CIPHER_PARAMS);
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
goto err;
|
||||
}
|
||||
/*
|
||||
* If prf NID unspecified see if cipher has a preference. An error is OK
|
||||
* here: just means use default PRF.
|
||||
*/
|
||||
if ((prf_nid == -1) &&
|
||||
EVP_CIPHER_CTX_ctrl(&ctx, EVP_CTRL_PBE_PRF_NID, 0, &prf_nid) <= 0) {
|
||||
ERR_clear_error();
|
||||
prf_nid = NID_hmacWithSHA1;
|
||||
}
|
||||
EVP_CIPHER_CTX_cleanup(&ctx);
|
||||
|
||||
/* If its RC2 then we'd better setup the key length */
|
||||
/* If its RC2 then we'd better setup the key length */
|
||||
|
||||
if(alg_nid == NID_rc2_cbc)
|
||||
keylen = EVP_CIPHER_key_length(cipher);
|
||||
else
|
||||
keylen = -1;
|
||||
if (alg_nid == NID_rc2_cbc)
|
||||
keylen = EVP_CIPHER_key_length(cipher);
|
||||
else
|
||||
keylen = -1;
|
||||
|
||||
/* Setup keyfunc */
|
||||
/* Setup keyfunc */
|
||||
|
||||
X509_ALGOR_free(pbe2->keyfunc);
|
||||
X509_ALGOR_free(pbe2->keyfunc);
|
||||
|
||||
pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
|
||||
pbe2->keyfunc = PKCS5_pbkdf2_set(iter, salt, saltlen, prf_nid, keylen);
|
||||
|
||||
if (!pbe2->keyfunc)
|
||||
goto merr;
|
||||
if (!pbe2->keyfunc)
|
||||
goto merr;
|
||||
|
||||
/* Now set up top level AlgorithmIdentifier */
|
||||
/* Now set up top level AlgorithmIdentifier */
|
||||
|
||||
if(!(ret = X509_ALGOR_new())) goto merr;
|
||||
if(!(ret->parameter = ASN1_TYPE_new())) goto merr;
|
||||
if (!(ret = X509_ALGOR_new()))
|
||||
goto merr;
|
||||
if (!(ret->parameter = ASN1_TYPE_new()))
|
||||
goto merr;
|
||||
|
||||
ret->algorithm = OBJ_nid2obj(NID_pbes2);
|
||||
ret->algorithm = OBJ_nid2obj(NID_pbes2);
|
||||
|
||||
/* Encode PBE2PARAM into parameter */
|
||||
/* Encode PBE2PARAM into parameter */
|
||||
|
||||
if(!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
|
||||
&ret->parameter->value.sequence)) goto merr;
|
||||
ret->parameter->type = V_ASN1_SEQUENCE;
|
||||
if (!ASN1_item_pack(pbe2, ASN1_ITEM_rptr(PBE2PARAM),
|
||||
&ret->parameter->value.sequence))
|
||||
goto merr;
|
||||
ret->parameter->type = V_ASN1_SEQUENCE;
|
||||
|
||||
PBE2PARAM_free(pbe2);
|
||||
pbe2 = NULL;
|
||||
PBE2PARAM_free(pbe2);
|
||||
pbe2 = NULL;
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
|
||||
merr:
|
||||
ASN1err(ASN1_F_PKCS5_PBE2_SET_IV,ERR_R_MALLOC_FAILURE);
|
||||
merr:
|
||||
ASN1err(ASN1_F_PKCS5_PBE2_SET_IV, ERR_R_MALLOC_FAILURE);
|
||||
|
||||
err:
|
||||
PBE2PARAM_free(pbe2);
|
||||
/* Note 'scheme' is freed as part of pbe2 */
|
||||
X509_ALGOR_free(kalg);
|
||||
X509_ALGOR_free(ret);
|
||||
err:
|
||||
PBE2PARAM_free(pbe2);
|
||||
/* Note 'scheme' is freed as part of pbe2 */
|
||||
X509_ALGOR_free(kalg);
|
||||
X509_ALGOR_free(ret);
|
||||
|
||||
return NULL;
|
||||
return NULL;
|
||||
|
||||
}
|
||||
|
||||
X509_ALGOR *PKCS5_pbe2_set(const EVP_CIPHER *cipher, int iter,
|
||||
unsigned char *salt, int saltlen)
|
||||
{
|
||||
return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
|
||||
}
|
||||
unsigned char *salt, int saltlen)
|
||||
{
|
||||
return PKCS5_pbe2_set_iv(cipher, iter, salt, saltlen, NULL, -1);
|
||||
}
|
||||
|
||||
X509_ALGOR *PKCS5_pbkdf2_set(int iter, unsigned char *salt, int saltlen,
|
||||
int prf_nid, int keylen)
|
||||
{
|
||||
X509_ALGOR *keyfunc = NULL;
|
||||
PBKDF2PARAM *kdf = NULL;
|
||||
ASN1_OCTET_STRING *osalt = NULL;
|
||||
int prf_nid, int keylen)
|
||||
{
|
||||
X509_ALGOR *keyfunc = NULL;
|
||||
PBKDF2PARAM *kdf = NULL;
|
||||
ASN1_OCTET_STRING *osalt = NULL;
|
||||
|
||||
if(!(kdf = PBKDF2PARAM_new()))
|
||||
goto merr;
|
||||
if(!(osalt = M_ASN1_OCTET_STRING_new()))
|
||||
goto merr;
|
||||
if (!(kdf = PBKDF2PARAM_new()))
|
||||
goto merr;
|
||||
if (!(osalt = M_ASN1_OCTET_STRING_new()))
|
||||
goto merr;
|
||||
|
||||
kdf->salt->value.octet_string = osalt;
|
||||
kdf->salt->type = V_ASN1_OCTET_STRING;
|
||||
kdf->salt->value.octet_string = osalt;
|
||||
kdf->salt->type = V_ASN1_OCTET_STRING;
|
||||
|
||||
if (!saltlen)
|
||||
saltlen = PKCS5_SALT_LEN;
|
||||
if (!(osalt->data = OPENSSL_malloc (saltlen)))
|
||||
goto merr;
|
||||
if (!saltlen)
|
||||
saltlen = PKCS5_SALT_LEN;
|
||||
if (!(osalt->data = OPENSSL_malloc(saltlen)))
|
||||
goto merr;
|
||||
|
||||
osalt->length = saltlen;
|
||||
osalt->length = saltlen;
|
||||
|
||||
if (salt)
|
||||
memcpy (osalt->data, salt, saltlen);
|
||||
else if (RAND_pseudo_bytes (osalt->data, saltlen) < 0)
|
||||
goto merr;
|
||||
if (salt)
|
||||
memcpy(osalt->data, salt, saltlen);
|
||||
else if (RAND_pseudo_bytes(osalt->data, saltlen) < 0)
|
||||
goto merr;
|
||||
|
||||
if(iter <= 0)
|
||||
iter = PKCS5_DEFAULT_ITER;
|
||||
if (iter <= 0)
|
||||
iter = PKCS5_DEFAULT_ITER;
|
||||
|
||||
if(!ASN1_INTEGER_set(kdf->iter, iter))
|
||||
goto merr;
|
||||
if (!ASN1_INTEGER_set(kdf->iter, iter))
|
||||
goto merr;
|
||||
|
||||
/* If have a key len set it up */
|
||||
/* If have a key len set it up */
|
||||
|
||||
if(keylen > 0)
|
||||
{
|
||||
if(!(kdf->keylength = M_ASN1_INTEGER_new()))
|
||||
goto merr;
|
||||
if(!ASN1_INTEGER_set (kdf->keylength, keylen))
|
||||
goto merr;
|
||||
}
|
||||
if (keylen > 0) {
|
||||
if (!(kdf->keylength = M_ASN1_INTEGER_new()))
|
||||
goto merr;
|
||||
if (!ASN1_INTEGER_set(kdf->keylength, keylen))
|
||||
goto merr;
|
||||
}
|
||||
|
||||
/* prf can stay NULL if we are using hmacWithSHA1 */
|
||||
if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1)
|
||||
{
|
||||
kdf->prf = X509_ALGOR_new();
|
||||
if (!kdf->prf)
|
||||
goto merr;
|
||||
X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid),
|
||||
V_ASN1_NULL, NULL);
|
||||
}
|
||||
/* prf can stay NULL if we are using hmacWithSHA1 */
|
||||
if (prf_nid > 0 && prf_nid != NID_hmacWithSHA1) {
|
||||
kdf->prf = X509_ALGOR_new();
|
||||
if (!kdf->prf)
|
||||
goto merr;
|
||||
X509_ALGOR_set0(kdf->prf, OBJ_nid2obj(prf_nid), V_ASN1_NULL, NULL);
|
||||
}
|
||||
|
||||
/* Finally setup the keyfunc structure */
|
||||
/* Finally setup the keyfunc structure */
|
||||
|
||||
keyfunc = X509_ALGOR_new();
|
||||
if (!keyfunc)
|
||||
goto merr;
|
||||
keyfunc = X509_ALGOR_new();
|
||||
if (!keyfunc)
|
||||
goto merr;
|
||||
|
||||
keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
|
||||
keyfunc->algorithm = OBJ_nid2obj(NID_id_pbkdf2);
|
||||
|
||||
/* Encode PBKDF2PARAM into parameter of pbe2 */
|
||||
/* Encode PBKDF2PARAM into parameter of pbe2 */
|
||||
|
||||
if(!(keyfunc->parameter = ASN1_TYPE_new()))
|
||||
goto merr;
|
||||
if (!(keyfunc->parameter = ASN1_TYPE_new()))
|
||||
goto merr;
|
||||
|
||||
if(!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
|
||||
&keyfunc->parameter->value.sequence))
|
||||
goto merr;
|
||||
keyfunc->parameter->type = V_ASN1_SEQUENCE;
|
||||
if (!ASN1_item_pack(kdf, ASN1_ITEM_rptr(PBKDF2PARAM),
|
||||
&keyfunc->parameter->value.sequence))
|
||||
goto merr;
|
||||
keyfunc->parameter->type = V_ASN1_SEQUENCE;
|
||||
|
||||
PBKDF2PARAM_free(kdf);
|
||||
return keyfunc;
|
||||
|
||||
merr:
|
||||
ASN1err(ASN1_F_PKCS5_PBKDF2_SET,ERR_R_MALLOC_FAILURE);
|
||||
PBKDF2PARAM_free(kdf);
|
||||
X509_ALGOR_free(keyfunc);
|
||||
return NULL;
|
||||
}
|
||||
PBKDF2PARAM_free(kdf);
|
||||
return keyfunc;
|
||||
|
||||
merr:
|
||||
ASN1err(ASN1_F_PKCS5_PBKDF2_SET, ERR_R_MALLOC_FAILURE);
|
||||
PBKDF2PARAM_free(kdf);
|
||||
X509_ALGOR_free(keyfunc);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* p8_pkey.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999-2005 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -63,93 +64,82 @@
|
||||
|
||||
/* Minor tweak to operation: zero private key data */
|
||||
static int pkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
void *exarg)
|
||||
void *exarg)
|
||||
{
|
||||
/* Since the structure must still be valid use ASN1_OP_FREE_PRE */
|
||||
if(operation == ASN1_OP_FREE_PRE) {
|
||||
PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
|
||||
if (key->pkey->value.octet_string)
|
||||
OPENSSL_cleanse(key->pkey->value.octet_string->data,
|
||||
key->pkey->value.octet_string->length);
|
||||
}
|
||||
return 1;
|
||||
/* Since the structure must still be valid use ASN1_OP_FREE_PRE */
|
||||
if (operation == ASN1_OP_FREE_PRE) {
|
||||
PKCS8_PRIV_KEY_INFO *key = (PKCS8_PRIV_KEY_INFO *)*pval;
|
||||
if (key->pkey && key->pkey->type == V_ASN1_OCTET_STRING
|
||||
&& key->pkey->value.octet_string != NULL)
|
||||
OPENSSL_cleanse(key->pkey->value.octet_string->data,
|
||||
key->pkey->value.octet_string->length);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
ASN1_SEQUENCE_cb(PKCS8_PRIV_KEY_INFO, pkey_cb) = {
|
||||
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR),
|
||||
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_ANY),
|
||||
ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0)
|
||||
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, version, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkeyalg, X509_ALGOR),
|
||||
ASN1_SIMPLE(PKCS8_PRIV_KEY_INFO, pkey, ASN1_ANY),
|
||||
ASN1_IMP_SET_OF_OPT(PKCS8_PRIV_KEY_INFO, attributes, X509_ATTRIBUTE, 0)
|
||||
} ASN1_SEQUENCE_END_cb(PKCS8_PRIV_KEY_INFO, PKCS8_PRIV_KEY_INFO)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(PKCS8_PRIV_KEY_INFO)
|
||||
|
||||
int PKCS8_pkey_set0(PKCS8_PRIV_KEY_INFO *priv, ASN1_OBJECT *aobj,
|
||||
int version,
|
||||
int ptype, void *pval,
|
||||
unsigned char *penc, int penclen)
|
||||
{
|
||||
unsigned char **ppenc = NULL;
|
||||
if (version >= 0)
|
||||
{
|
||||
if (!ASN1_INTEGER_set(priv->version, version))
|
||||
return 0;
|
||||
}
|
||||
if (penc)
|
||||
{
|
||||
int pmtype;
|
||||
ASN1_OCTET_STRING *oct;
|
||||
oct = ASN1_OCTET_STRING_new();
|
||||
if (!oct)
|
||||
return 0;
|
||||
oct->data = penc;
|
||||
ppenc = &oct->data;
|
||||
oct->length = penclen;
|
||||
if (priv->broken == PKCS8_NO_OCTET)
|
||||
pmtype = V_ASN1_SEQUENCE;
|
||||
else
|
||||
pmtype = V_ASN1_OCTET_STRING;
|
||||
ASN1_TYPE_set(priv->pkey, pmtype, oct);
|
||||
}
|
||||
if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval))
|
||||
{
|
||||
/* If call fails do not swallow 'enc' */
|
||||
if (ppenc)
|
||||
*ppenc = NULL;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
int version,
|
||||
int ptype, void *pval, unsigned char *penc, int penclen)
|
||||
{
|
||||
unsigned char **ppenc = NULL;
|
||||
if (version >= 0) {
|
||||
if (!ASN1_INTEGER_set(priv->version, version))
|
||||
return 0;
|
||||
}
|
||||
if (penc) {
|
||||
int pmtype;
|
||||
ASN1_OCTET_STRING *oct;
|
||||
oct = ASN1_OCTET_STRING_new();
|
||||
if (!oct)
|
||||
return 0;
|
||||
oct->data = penc;
|
||||
ppenc = &oct->data;
|
||||
oct->length = penclen;
|
||||
if (priv->broken == PKCS8_NO_OCTET)
|
||||
pmtype = V_ASN1_SEQUENCE;
|
||||
else
|
||||
pmtype = V_ASN1_OCTET_STRING;
|
||||
ASN1_TYPE_set(priv->pkey, pmtype, oct);
|
||||
}
|
||||
if (!X509_ALGOR_set0(priv->pkeyalg, aobj, ptype, pval)) {
|
||||
/* If call fails do not swallow 'enc' */
|
||||
if (ppenc)
|
||||
*ppenc = NULL;
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int PKCS8_pkey_get0(ASN1_OBJECT **ppkalg,
|
||||
const unsigned char **pk, int *ppklen,
|
||||
X509_ALGOR **pa,
|
||||
PKCS8_PRIV_KEY_INFO *p8)
|
||||
{
|
||||
if (ppkalg)
|
||||
*ppkalg = p8->pkeyalg->algorithm;
|
||||
if(p8->pkey->type == V_ASN1_OCTET_STRING)
|
||||
{
|
||||
p8->broken = PKCS8_OK;
|
||||
if (pk)
|
||||
{
|
||||
*pk = p8->pkey->value.octet_string->data;
|
||||
*ppklen = p8->pkey->value.octet_string->length;
|
||||
}
|
||||
}
|
||||
else if (p8->pkey->type == V_ASN1_SEQUENCE)
|
||||
{
|
||||
p8->broken = PKCS8_NO_OCTET;
|
||||
if (pk)
|
||||
{
|
||||
*pk = p8->pkey->value.sequence->data;
|
||||
*ppklen = p8->pkey->value.sequence->length;
|
||||
}
|
||||
}
|
||||
else
|
||||
return 0;
|
||||
if (pa)
|
||||
*pa = p8->pkeyalg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
const unsigned char **pk, int *ppklen,
|
||||
X509_ALGOR **pa, PKCS8_PRIV_KEY_INFO *p8)
|
||||
{
|
||||
if (ppkalg)
|
||||
*ppkalg = p8->pkeyalg->algorithm;
|
||||
if (p8->pkey->type == V_ASN1_OCTET_STRING) {
|
||||
p8->broken = PKCS8_OK;
|
||||
if (pk) {
|
||||
*pk = p8->pkey->value.octet_string->data;
|
||||
*ppklen = p8->pkey->value.octet_string->length;
|
||||
}
|
||||
} else if (p8->pkey->type == V_ASN1_SEQUENCE) {
|
||||
p8->broken = PKCS8_NO_OCTET;
|
||||
if (pk) {
|
||||
*pk = p8->pkey->value.sequence->data;
|
||||
*ppklen = p8->pkey->value.sequence->length;
|
||||
}
|
||||
} else
|
||||
return 0;
|
||||
if (pa)
|
||||
*pa = p8->pkeyalg;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* t_bitst.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -62,41 +63,43 @@
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
int ASN1_BIT_STRING_name_print(BIO *out, ASN1_BIT_STRING *bs,
|
||||
BIT_STRING_BITNAME *tbl, int indent)
|
||||
BIT_STRING_BITNAME *tbl, int indent)
|
||||
{
|
||||
BIT_STRING_BITNAME *bnam;
|
||||
char first = 1;
|
||||
BIO_printf(out, "%*s", indent, "");
|
||||
for(bnam = tbl; bnam->lname; bnam++) {
|
||||
if(ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
|
||||
if(!first) BIO_puts(out, ", ");
|
||||
BIO_puts(out, bnam->lname);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
BIO_puts(out, "\n");
|
||||
return 1;
|
||||
BIT_STRING_BITNAME *bnam;
|
||||
char first = 1;
|
||||
BIO_printf(out, "%*s", indent, "");
|
||||
for (bnam = tbl; bnam->lname; bnam++) {
|
||||
if (ASN1_BIT_STRING_get_bit(bs, bnam->bitnum)) {
|
||||
if (!first)
|
||||
BIO_puts(out, ", ");
|
||||
BIO_puts(out, bnam->lname);
|
||||
first = 0;
|
||||
}
|
||||
}
|
||||
BIO_puts(out, "\n");
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ASN1_BIT_STRING_set_asc(ASN1_BIT_STRING *bs, char *name, int value,
|
||||
BIT_STRING_BITNAME *tbl)
|
||||
BIT_STRING_BITNAME *tbl)
|
||||
{
|
||||
int bitnum;
|
||||
bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
|
||||
if(bitnum < 0) return 0;
|
||||
if(bs) {
|
||||
if(!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
int bitnum;
|
||||
bitnum = ASN1_BIT_STRING_num_asc(name, tbl);
|
||||
if (bitnum < 0)
|
||||
return 0;
|
||||
if (bs) {
|
||||
if (!ASN1_BIT_STRING_set_bit(bs, bitnum, value))
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ASN1_BIT_STRING_num_asc(char *name, BIT_STRING_BITNAME *tbl)
|
||||
{
|
||||
BIT_STRING_BITNAME *bnam;
|
||||
for(bnam = tbl; bnam->lname; bnam++) {
|
||||
if(!strcmp(bnam->sname, name) ||
|
||||
!strcmp(bnam->lname, name) ) return bnam->bitnum;
|
||||
}
|
||||
return -1;
|
||||
BIT_STRING_BITNAME *bnam;
|
||||
for (bnam = tbl; bnam->lname; bnam++) {
|
||||
if (!strcmp(bnam->sname, name) || !strcmp(bnam->lname, name))
|
||||
return bnam->bitnum;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* t_crl.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -66,67 +67,67 @@
|
||||
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
int X509_CRL_print_fp(FILE *fp, X509_CRL *x)
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
|
||||
if ((b=BIO_new(BIO_s_file())) == NULL)
|
||||
{
|
||||
X509err(X509_F_X509_CRL_PRINT_FP,ERR_R_BUF_LIB);
|
||||
return(0);
|
||||
}
|
||||
BIO_set_fp(b,fp,BIO_NOCLOSE);
|
||||
ret=X509_CRL_print(b, x);
|
||||
BIO_free(b);
|
||||
return(ret);
|
||||
}
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
X509err(X509_F_X509_CRL_PRINT_FP, ERR_R_BUF_LIB);
|
||||
return (0);
|
||||
}
|
||||
BIO_set_fp(b, fp, BIO_NOCLOSE);
|
||||
ret = X509_CRL_print(b, x);
|
||||
BIO_free(b);
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
int X509_CRL_print(BIO *out, X509_CRL *x)
|
||||
{
|
||||
STACK_OF(X509_REVOKED) *rev;
|
||||
X509_REVOKED *r;
|
||||
long l;
|
||||
int i;
|
||||
char *p;
|
||||
STACK_OF(X509_REVOKED) *rev;
|
||||
X509_REVOKED *r;
|
||||
long l;
|
||||
int i;
|
||||
char *p;
|
||||
|
||||
BIO_printf(out, "Certificate Revocation List (CRL):\n");
|
||||
l = X509_CRL_get_version(x);
|
||||
BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l+1, l);
|
||||
i = OBJ_obj2nid(x->sig_alg->algorithm);
|
||||
X509_signature_print(out, x->sig_alg, NULL);
|
||||
p=X509_NAME_oneline(X509_CRL_get_issuer(x),NULL,0);
|
||||
BIO_printf(out,"%8sIssuer: %s\n","",p);
|
||||
OPENSSL_free(p);
|
||||
BIO_printf(out,"%8sLast Update: ","");
|
||||
ASN1_TIME_print(out,X509_CRL_get_lastUpdate(x));
|
||||
BIO_printf(out,"\n%8sNext Update: ","");
|
||||
if (X509_CRL_get_nextUpdate(x))
|
||||
ASN1_TIME_print(out,X509_CRL_get_nextUpdate(x));
|
||||
else BIO_printf(out,"NONE");
|
||||
BIO_printf(out,"\n");
|
||||
BIO_printf(out, "Certificate Revocation List (CRL):\n");
|
||||
l = X509_CRL_get_version(x);
|
||||
BIO_printf(out, "%8sVersion %lu (0x%lx)\n", "", l + 1, l);
|
||||
i = OBJ_obj2nid(x->sig_alg->algorithm);
|
||||
X509_signature_print(out, x->sig_alg, NULL);
|
||||
p = X509_NAME_oneline(X509_CRL_get_issuer(x), NULL, 0);
|
||||
BIO_printf(out, "%8sIssuer: %s\n", "", p);
|
||||
OPENSSL_free(p);
|
||||
BIO_printf(out, "%8sLast Update: ", "");
|
||||
ASN1_TIME_print(out, X509_CRL_get_lastUpdate(x));
|
||||
BIO_printf(out, "\n%8sNext Update: ", "");
|
||||
if (X509_CRL_get_nextUpdate(x))
|
||||
ASN1_TIME_print(out, X509_CRL_get_nextUpdate(x));
|
||||
else
|
||||
BIO_printf(out, "NONE");
|
||||
BIO_printf(out, "\n");
|
||||
|
||||
X509V3_extensions_print(out, "CRL extensions",
|
||||
x->crl->extensions, 0, 8);
|
||||
X509V3_extensions_print(out, "CRL extensions", x->crl->extensions, 0, 8);
|
||||
|
||||
rev = X509_CRL_get_REVOKED(x);
|
||||
rev = X509_CRL_get_REVOKED(x);
|
||||
|
||||
if(sk_X509_REVOKED_num(rev) > 0)
|
||||
BIO_printf(out, "Revoked Certificates:\n");
|
||||
else BIO_printf(out, "No Revoked Certificates.\n");
|
||||
if (sk_X509_REVOKED_num(rev) > 0)
|
||||
BIO_printf(out, "Revoked Certificates:\n");
|
||||
else
|
||||
BIO_printf(out, "No Revoked Certificates.\n");
|
||||
|
||||
for(i = 0; i < sk_X509_REVOKED_num(rev); i++) {
|
||||
r = sk_X509_REVOKED_value(rev, i);
|
||||
BIO_printf(out," Serial Number: ");
|
||||
i2a_ASN1_INTEGER(out,r->serialNumber);
|
||||
BIO_printf(out,"\n Revocation Date: ");
|
||||
ASN1_TIME_print(out,r->revocationDate);
|
||||
BIO_printf(out,"\n");
|
||||
X509V3_extensions_print(out, "CRL entry extensions",
|
||||
r->extensions, 0, 8);
|
||||
}
|
||||
X509_signature_print(out, x->sig_alg, x->signature);
|
||||
for (i = 0; i < sk_X509_REVOKED_num(rev); i++) {
|
||||
r = sk_X509_REVOKED_value(rev, i);
|
||||
BIO_printf(out, " Serial Number: ");
|
||||
i2a_ASN1_INTEGER(out, r->serialNumber);
|
||||
BIO_printf(out, "\n Revocation Date: ");
|
||||
ASN1_TIME_print(out, r->revocationDate);
|
||||
BIO_printf(out, "\n");
|
||||
X509V3_extensions_print(out, "CRL entry extensions",
|
||||
r->extensions, 0, 8);
|
||||
}
|
||||
X509_signature_print(out, x->sig_alg, x->signature);
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -63,52 +63,51 @@
|
||||
#include <openssl/bn.h>
|
||||
|
||||
int ASN1_bn_print(BIO *bp, const char *number, const BIGNUM *num,
|
||||
unsigned char *buf, int off)
|
||||
{
|
||||
int n,i;
|
||||
const char *neg;
|
||||
unsigned char *buf, int off)
|
||||
{
|
||||
int n, i;
|
||||
const char *neg;
|
||||
|
||||
if (num == NULL) return(1);
|
||||
neg = (BN_is_negative(num))?"-":"";
|
||||
if(!BIO_indent(bp,off,128))
|
||||
return 0;
|
||||
if (BN_is_zero(num))
|
||||
{
|
||||
if (BIO_printf(bp, "%s 0\n", number) <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
if (num == NULL)
|
||||
return (1);
|
||||
neg = (BN_is_negative(num)) ? "-" : "";
|
||||
if (!BIO_indent(bp, off, 128))
|
||||
return 0;
|
||||
if (BN_is_zero(num)) {
|
||||
if (BIO_printf(bp, "%s 0\n", number) <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (BN_num_bytes(num) <= BN_BYTES)
|
||||
{
|
||||
if (BIO_printf(bp,"%s %s%lu (%s0x%lx)\n",number,neg,
|
||||
(unsigned long)num->d[0],neg,(unsigned long)num->d[0])
|
||||
<= 0) return(0);
|
||||
}
|
||||
else
|
||||
{
|
||||
buf[0]=0;
|
||||
if (BIO_printf(bp,"%s%s",number,
|
||||
(neg[0] == '-')?" (Negative)":"") <= 0)
|
||||
return(0);
|
||||
n=BN_bn2bin(num,&buf[1]);
|
||||
|
||||
if (buf[1] & 0x80)
|
||||
n++;
|
||||
else buf++;
|
||||
if (BN_num_bytes(num) <= BN_BYTES) {
|
||||
if (BIO_printf(bp, "%s %s%lu (%s0x%lx)\n", number, neg,
|
||||
(unsigned long)num->d[0], neg,
|
||||
(unsigned long)num->d[0])
|
||||
<= 0)
|
||||
return (0);
|
||||
} else {
|
||||
buf[0] = 0;
|
||||
if (BIO_printf(bp, "%s%s", number,
|
||||
(neg[0] == '-') ? " (Negative)" : "") <= 0)
|
||||
return (0);
|
||||
n = BN_bn2bin(num, &buf[1]);
|
||||
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
if ((i%15) == 0)
|
||||
{
|
||||
if(BIO_puts(bp,"\n") <= 0
|
||||
|| !BIO_indent(bp,off+4,128))
|
||||
return 0;
|
||||
}
|
||||
if (BIO_printf(bp,"%02x%s",buf[i],((i+1) == n)?"":":")
|
||||
<= 0) return(0);
|
||||
}
|
||||
if (BIO_write(bp,"\n",1) <= 0) return(0);
|
||||
}
|
||||
return(1);
|
||||
}
|
||||
if (buf[1] & 0x80)
|
||||
n++;
|
||||
else
|
||||
buf++;
|
||||
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((i % 15) == 0) {
|
||||
if (BIO_puts(bp, "\n") <= 0 || !BIO_indent(bp, off + 4, 128))
|
||||
return 0;
|
||||
}
|
||||
if (BIO_printf(bp, "%02x%s", buf[i], ((i + 1) == n) ? "" : ":")
|
||||
<= 0)
|
||||
return (0);
|
||||
}
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
return (0);
|
||||
}
|
||||
return (1);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -64,203 +64,191 @@
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
#include <openssl/rsa.h>
|
||||
# include <openssl/rsa.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
#include <openssl/dsa.h>
|
||||
# include <openssl/dsa.h>
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
int X509_REQ_print_fp(FILE *fp, X509_REQ *x)
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
|
||||
if ((b=BIO_new(BIO_s_file())) == NULL)
|
||||
{
|
||||
X509err(X509_F_X509_REQ_PRINT_FP,ERR_R_BUF_LIB);
|
||||
return(0);
|
||||
}
|
||||
BIO_set_fp(b,fp,BIO_NOCLOSE);
|
||||
ret=X509_REQ_print(b, x);
|
||||
BIO_free(b);
|
||||
return(ret);
|
||||
}
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
X509err(X509_F_X509_REQ_PRINT_FP, ERR_R_BUF_LIB);
|
||||
return (0);
|
||||
}
|
||||
BIO_set_fp(b, fp, BIO_NOCLOSE);
|
||||
ret = X509_REQ_print(b, x);
|
||||
BIO_free(b);
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags, unsigned long cflag)
|
||||
{
|
||||
unsigned long l;
|
||||
int i;
|
||||
const char *neg;
|
||||
X509_REQ_INFO *ri;
|
||||
EVP_PKEY *pkey;
|
||||
STACK_OF(X509_ATTRIBUTE) *sk;
|
||||
STACK_OF(X509_EXTENSION) *exts;
|
||||
char mlch = ' ';
|
||||
int nmindent = 0;
|
||||
int X509_REQ_print_ex(BIO *bp, X509_REQ *x, unsigned long nmflags,
|
||||
unsigned long cflag)
|
||||
{
|
||||
unsigned long l;
|
||||
int i;
|
||||
const char *neg;
|
||||
X509_REQ_INFO *ri;
|
||||
EVP_PKEY *pkey;
|
||||
STACK_OF(X509_ATTRIBUTE) *sk;
|
||||
STACK_OF(X509_EXTENSION) *exts;
|
||||
char mlch = ' ';
|
||||
int nmindent = 0;
|
||||
|
||||
if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
|
||||
mlch = '\n';
|
||||
nmindent = 12;
|
||||
}
|
||||
if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
|
||||
mlch = '\n';
|
||||
nmindent = 12;
|
||||
}
|
||||
|
||||
if(nmflags == X509_FLAG_COMPAT)
|
||||
nmindent = 16;
|
||||
if (nmflags == X509_FLAG_COMPAT)
|
||||
nmindent = 16;
|
||||
|
||||
ri = x->req_info;
|
||||
if (!(cflag & X509_FLAG_NO_HEADER)) {
|
||||
if (BIO_write(bp, "Certificate Request:\n", 21) <= 0)
|
||||
goto err;
|
||||
if (BIO_write(bp, " Data:\n", 10) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (!(cflag & X509_FLAG_NO_VERSION)) {
|
||||
neg = (ri->version->type == V_ASN1_NEG_INTEGER) ? "-" : "";
|
||||
l = 0;
|
||||
for (i = 0; i < ri->version->length; i++) {
|
||||
l <<= 8;
|
||||
l += ri->version->data[i];
|
||||
}
|
||||
if (BIO_printf(bp, "%8sVersion: %s%lu (%s0x%lx)\n", "", neg, l, neg,
|
||||
l) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (!(cflag & X509_FLAG_NO_SUBJECT)) {
|
||||
if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
|
||||
goto err;
|
||||
if (X509_NAME_print_ex(bp, ri->subject, nmindent, nmflags) < 0)
|
||||
goto err;
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (!(cflag & X509_FLAG_NO_PUBKEY)) {
|
||||
if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0)
|
||||
goto err;
|
||||
if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
|
||||
goto err;
|
||||
if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0)
|
||||
goto err;
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
goto err;
|
||||
|
||||
ri=x->req_info;
|
||||
if(!(cflag & X509_FLAG_NO_HEADER))
|
||||
{
|
||||
if (BIO_write(bp,"Certificate Request:\n",21) <= 0) goto err;
|
||||
if (BIO_write(bp," Data:\n",10) <= 0) goto err;
|
||||
}
|
||||
if(!(cflag & X509_FLAG_NO_VERSION))
|
||||
{
|
||||
neg=(ri->version->type == V_ASN1_NEG_INTEGER)?"-":"";
|
||||
l=0;
|
||||
for (i=0; i<ri->version->length; i++)
|
||||
{ l<<=8; l+=ri->version->data[i]; }
|
||||
if(BIO_printf(bp,"%8sVersion: %s%lu (%s0x%lx)\n","",neg,l,neg,
|
||||
l) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if(!(cflag & X509_FLAG_NO_SUBJECT))
|
||||
{
|
||||
if (BIO_printf(bp," Subject:%c",mlch) <= 0) goto err;
|
||||
if (X509_NAME_print_ex(bp,ri->subject,nmindent, nmflags) < 0) goto err;
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto err;
|
||||
pkey = X509_REQ_get_pubkey(x);
|
||||
if (pkey == NULL) {
|
||||
BIO_printf(bp, "%12sUnable to load Public Key\n", "");
|
||||
ERR_print_errors(bp);
|
||||
} else {
|
||||
EVP_PKEY_print_public(bp, pkey, 16, NULL);
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(cflag & X509_FLAG_NO_ATTRIBUTES)) {
|
||||
/* may not be */
|
||||
if (BIO_printf(bp, "%8sAttributes:\n", "") <= 0)
|
||||
goto err;
|
||||
|
||||
sk = x->req_info->attributes;
|
||||
if (sk_X509_ATTRIBUTE_num(sk) == 0) {
|
||||
if (BIO_printf(bp, "%12sa0:00\n", "") <= 0)
|
||||
goto err;
|
||||
} else {
|
||||
for (i = 0; i < sk_X509_ATTRIBUTE_num(sk); i++) {
|
||||
ASN1_TYPE *at;
|
||||
X509_ATTRIBUTE *a;
|
||||
ASN1_BIT_STRING *bs = NULL;
|
||||
ASN1_TYPE *t;
|
||||
int j, type = 0, count = 1, ii = 0;
|
||||
|
||||
a = sk_X509_ATTRIBUTE_value(sk, i);
|
||||
if (X509_REQ_extension_nid(OBJ_obj2nid(a->object)))
|
||||
continue;
|
||||
if (BIO_printf(bp, "%12s", "") <= 0)
|
||||
goto err;
|
||||
if ((j = i2a_ASN1_OBJECT(bp, a->object)) > 0) {
|
||||
if (a->single) {
|
||||
t = a->value.single;
|
||||
type = t->type;
|
||||
bs = t->value.bit_string;
|
||||
} else {
|
||||
ii = 0;
|
||||
count = sk_ASN1_TYPE_num(a->value.set);
|
||||
get_next:
|
||||
at = sk_ASN1_TYPE_value(a->value.set, ii);
|
||||
type = at->type;
|
||||
bs = at->value.asn1_string;
|
||||
}
|
||||
}
|
||||
if(!(cflag & X509_FLAG_NO_PUBKEY))
|
||||
{
|
||||
if (BIO_write(bp," Subject Public Key Info:\n",33) <= 0)
|
||||
goto err;
|
||||
if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
|
||||
goto err;
|
||||
if (i2a_ASN1_OBJECT(bp, ri->pubkey->algor->algorithm) <= 0)
|
||||
goto err;
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
goto err;
|
||||
for (j = 25 - j; j > 0; j--)
|
||||
if (BIO_write(bp, " ", 1) != 1)
|
||||
goto err;
|
||||
if (BIO_puts(bp, ":") <= 0)
|
||||
goto err;
|
||||
if ((type == V_ASN1_PRINTABLESTRING) ||
|
||||
(type == V_ASN1_T61STRING) ||
|
||||
(type == V_ASN1_IA5STRING)) {
|
||||
if (BIO_write(bp, (char *)bs->data, bs->length)
|
||||
!= bs->length)
|
||||
goto err;
|
||||
BIO_puts(bp, "\n");
|
||||
} else {
|
||||
BIO_puts(bp, "unable to print attribute\n");
|
||||
}
|
||||
if (++ii < count)
|
||||
goto get_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!(cflag & X509_FLAG_NO_EXTENSIONS)) {
|
||||
exts = X509_REQ_get_extensions(x);
|
||||
if (exts) {
|
||||
BIO_printf(bp, "%8sRequested Extensions:\n", "");
|
||||
for (i = 0; i < sk_X509_EXTENSION_num(exts); i++) {
|
||||
ASN1_OBJECT *obj;
|
||||
X509_EXTENSION *ex;
|
||||
int j;
|
||||
ex = sk_X509_EXTENSION_value(exts, i);
|
||||
if (BIO_printf(bp, "%12s", "") <= 0)
|
||||
goto err;
|
||||
obj = X509_EXTENSION_get_object(ex);
|
||||
i2a_ASN1_OBJECT(bp, obj);
|
||||
j = X509_EXTENSION_get_critical(ex);
|
||||
if (BIO_printf(bp, ": %s\n", j ? "critical" : "") <= 0)
|
||||
goto err;
|
||||
if (!X509V3_EXT_print(bp, ex, cflag, 16)) {
|
||||
BIO_printf(bp, "%16s", "");
|
||||
M_ASN1_OCTET_STRING_print(bp, ex->value);
|
||||
}
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto err;
|
||||
}
|
||||
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
|
||||
}
|
||||
}
|
||||
|
||||
pkey=X509_REQ_get_pubkey(x);
|
||||
if (pkey == NULL)
|
||||
{
|
||||
BIO_printf(bp,"%12sUnable to load Public Key\n","");
|
||||
ERR_print_errors(bp);
|
||||
}
|
||||
else
|
||||
{
|
||||
EVP_PKEY_print_public(bp, pkey, 16, NULL);
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
}
|
||||
if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
|
||||
if (!X509_signature_print(bp, x->sig_alg, x->signature))
|
||||
goto err;
|
||||
}
|
||||
|
||||
if(!(cflag & X509_FLAG_NO_ATTRIBUTES))
|
||||
{
|
||||
/* may not be */
|
||||
if(BIO_printf(bp,"%8sAttributes:\n","") <= 0)
|
||||
goto err;
|
||||
|
||||
sk=x->req_info->attributes;
|
||||
if (sk_X509_ATTRIBUTE_num(sk) == 0)
|
||||
{
|
||||
if(BIO_printf(bp,"%12sa0:00\n","") <= 0)
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
for (i=0; i<sk_X509_ATTRIBUTE_num(sk); i++)
|
||||
{
|
||||
ASN1_TYPE *at;
|
||||
X509_ATTRIBUTE *a;
|
||||
ASN1_BIT_STRING *bs=NULL;
|
||||
ASN1_TYPE *t;
|
||||
int j,type=0,count=1,ii=0;
|
||||
|
||||
a=sk_X509_ATTRIBUTE_value(sk,i);
|
||||
if(X509_REQ_extension_nid(OBJ_obj2nid(a->object)))
|
||||
continue;
|
||||
if(BIO_printf(bp,"%12s","") <= 0)
|
||||
goto err;
|
||||
if ((j=i2a_ASN1_OBJECT(bp,a->object)) > 0)
|
||||
{
|
||||
if (a->single)
|
||||
{
|
||||
t=a->value.single;
|
||||
type=t->type;
|
||||
bs=t->value.bit_string;
|
||||
}
|
||||
else
|
||||
{
|
||||
ii=0;
|
||||
count=sk_ASN1_TYPE_num(a->value.set);
|
||||
get_next:
|
||||
at=sk_ASN1_TYPE_value(a->value.set,ii);
|
||||
type=at->type;
|
||||
bs=at->value.asn1_string;
|
||||
}
|
||||
}
|
||||
for (j=25-j; j>0; j--)
|
||||
if (BIO_write(bp," ",1) != 1) goto err;
|
||||
if (BIO_puts(bp,":") <= 0) goto err;
|
||||
if ( (type == V_ASN1_PRINTABLESTRING) ||
|
||||
(type == V_ASN1_T61STRING) ||
|
||||
(type == V_ASN1_IA5STRING))
|
||||
{
|
||||
if (BIO_write(bp,(char *)bs->data,bs->length)
|
||||
!= bs->length)
|
||||
goto err;
|
||||
BIO_puts(bp,"\n");
|
||||
}
|
||||
else
|
||||
{
|
||||
BIO_puts(bp,"unable to print attribute\n");
|
||||
}
|
||||
if (++ii < count) goto get_next;
|
||||
}
|
||||
}
|
||||
}
|
||||
if(!(cflag & X509_FLAG_NO_EXTENSIONS))
|
||||
{
|
||||
exts = X509_REQ_get_extensions(x);
|
||||
if(exts)
|
||||
{
|
||||
BIO_printf(bp,"%8sRequested Extensions:\n","");
|
||||
for (i=0; i<sk_X509_EXTENSION_num(exts); i++)
|
||||
{
|
||||
ASN1_OBJECT *obj;
|
||||
X509_EXTENSION *ex;
|
||||
int j;
|
||||
ex=sk_X509_EXTENSION_value(exts, i);
|
||||
if (BIO_printf(bp,"%12s","") <= 0) goto err;
|
||||
obj=X509_EXTENSION_get_object(ex);
|
||||
i2a_ASN1_OBJECT(bp,obj);
|
||||
j=X509_EXTENSION_get_critical(ex);
|
||||
if (BIO_printf(bp,": %s\n",j?"critical":"") <= 0)
|
||||
goto err;
|
||||
if(!X509V3_EXT_print(bp, ex, cflag, 16))
|
||||
{
|
||||
BIO_printf(bp, "%16s", "");
|
||||
M_ASN1_OCTET_STRING_print(bp,ex->value);
|
||||
}
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto err;
|
||||
}
|
||||
sk_X509_EXTENSION_pop_free(exts, X509_EXTENSION_free);
|
||||
}
|
||||
}
|
||||
|
||||
if(!(cflag & X509_FLAG_NO_SIGDUMP))
|
||||
{
|
||||
if(!X509_signature_print(bp, x->sig_alg, x->signature)) goto err;
|
||||
}
|
||||
|
||||
return(1);
|
||||
err:
|
||||
X509err(X509_F_X509_REQ_PRINT_EX,ERR_R_BUF_LIB);
|
||||
return(0);
|
||||
}
|
||||
return (1);
|
||||
err:
|
||||
X509err(X509_F_X509_REQ_PRINT_EX, ERR_R_BUF_LIB);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int X509_REQ_print(BIO *bp, X509_REQ *x)
|
||||
{
|
||||
return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
|
||||
}
|
||||
{
|
||||
return X509_REQ_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* t_spki.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -61,10 +62,10 @@
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/asn1.h>
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
#include <openssl/rsa.h>
|
||||
# include <openssl/rsa.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
#include <openssl/dsa.h>
|
||||
# include <openssl/dsa.h>
|
||||
#endif
|
||||
#include <openssl/bn.h>
|
||||
|
||||
@ -72,36 +73,36 @@
|
||||
|
||||
int NETSCAPE_SPKI_print(BIO *out, NETSCAPE_SPKI *spki)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
ASN1_IA5STRING *chal;
|
||||
int i, n;
|
||||
char *s;
|
||||
BIO_printf(out, "Netscape SPKI:\n");
|
||||
i=OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm);
|
||||
BIO_printf(out," Public Key Algorithm: %s\n",
|
||||
(i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
|
||||
pkey = X509_PUBKEY_get(spki->spkac->pubkey);
|
||||
if(!pkey) BIO_printf(out, " Unable to load public key\n");
|
||||
else
|
||||
{
|
||||
EVP_PKEY_print_public(out, pkey, 4, NULL);
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
chal = spki->spkac->challenge;
|
||||
if(chal->length)
|
||||
BIO_printf(out, " Challenge String: %s\n", chal->data);
|
||||
i=OBJ_obj2nid(spki->sig_algor->algorithm);
|
||||
BIO_printf(out," Signature Algorithm: %s",
|
||||
(i == NID_undef)?"UNKNOWN":OBJ_nid2ln(i));
|
||||
EVP_PKEY *pkey;
|
||||
ASN1_IA5STRING *chal;
|
||||
int i, n;
|
||||
char *s;
|
||||
BIO_printf(out, "Netscape SPKI:\n");
|
||||
i = OBJ_obj2nid(spki->spkac->pubkey->algor->algorithm);
|
||||
BIO_printf(out, " Public Key Algorithm: %s\n",
|
||||
(i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
|
||||
pkey = X509_PUBKEY_get(spki->spkac->pubkey);
|
||||
if (!pkey)
|
||||
BIO_printf(out, " Unable to load public key\n");
|
||||
else {
|
||||
EVP_PKEY_print_public(out, pkey, 4, NULL);
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
chal = spki->spkac->challenge;
|
||||
if (chal->length)
|
||||
BIO_printf(out, " Challenge String: %s\n", chal->data);
|
||||
i = OBJ_obj2nid(spki->sig_algor->algorithm);
|
||||
BIO_printf(out, " Signature Algorithm: %s",
|
||||
(i == NID_undef) ? "UNKNOWN" : OBJ_nid2ln(i));
|
||||
|
||||
n=spki->signature->length;
|
||||
s=(char *)spki->signature->data;
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
if ((i%18) == 0) BIO_write(out,"\n ",7);
|
||||
BIO_printf(out,"%02x%s",(unsigned char)s[i],
|
||||
((i+1) == n)?"":":");
|
||||
}
|
||||
BIO_write(out,"\n",1);
|
||||
return 1;
|
||||
n = spki->signature->length;
|
||||
s = (char *)spki->signature->data;
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((i % 18) == 0)
|
||||
BIO_write(out, "\n ", 7);
|
||||
BIO_printf(out, "%02x%s", (unsigned char)s[i],
|
||||
((i + 1) == n) ? "" : ":");
|
||||
}
|
||||
BIO_write(out, "\n", 1);
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -61,13 +61,13 @@
|
||||
#include <openssl/buffer.h>
|
||||
#include <openssl/bn.h>
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
#include <openssl/rsa.h>
|
||||
# include <openssl/rsa.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
#include <openssl/dsa.h>
|
||||
# include <openssl/dsa.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_EC
|
||||
#include <openssl/ec.h>
|
||||
# include <openssl/ec.h>
|
||||
#endif
|
||||
#include <openssl/objects.h>
|
||||
#include <openssl/x509.h>
|
||||
@ -76,453 +76,465 @@
|
||||
|
||||
#ifndef OPENSSL_NO_FP_API
|
||||
int X509_print_fp(FILE *fp, X509 *x)
|
||||
{
|
||||
return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
|
||||
}
|
||||
{
|
||||
return X509_print_ex_fp(fp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
|
||||
}
|
||||
|
||||
int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag, unsigned long cflag)
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
int X509_print_ex_fp(FILE *fp, X509 *x, unsigned long nmflag,
|
||||
unsigned long cflag)
|
||||
{
|
||||
BIO *b;
|
||||
int ret;
|
||||
|
||||
if ((b=BIO_new(BIO_s_file())) == NULL)
|
||||
{
|
||||
X509err(X509_F_X509_PRINT_EX_FP,ERR_R_BUF_LIB);
|
||||
return(0);
|
||||
}
|
||||
BIO_set_fp(b,fp,BIO_NOCLOSE);
|
||||
ret=X509_print_ex(b, x, nmflag, cflag);
|
||||
BIO_free(b);
|
||||
return(ret);
|
||||
}
|
||||
if ((b = BIO_new(BIO_s_file())) == NULL) {
|
||||
X509err(X509_F_X509_PRINT_EX_FP, ERR_R_BUF_LIB);
|
||||
return (0);
|
||||
}
|
||||
BIO_set_fp(b, fp, BIO_NOCLOSE);
|
||||
ret = X509_print_ex(b, x, nmflag, cflag);
|
||||
BIO_free(b);
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
int X509_print(BIO *bp, X509 *x)
|
||||
{
|
||||
return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
|
||||
return X509_print_ex(bp, x, XN_FLAG_COMPAT, X509_FLAG_COMPAT);
|
||||
}
|
||||
|
||||
int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags, unsigned long cflag)
|
||||
{
|
||||
long l;
|
||||
int ret=0,i;
|
||||
char *m=NULL,mlch = ' ';
|
||||
int nmindent = 0;
|
||||
X509_CINF *ci;
|
||||
ASN1_INTEGER *bs;
|
||||
EVP_PKEY *pkey=NULL;
|
||||
const char *neg;
|
||||
int X509_print_ex(BIO *bp, X509 *x, unsigned long nmflags,
|
||||
unsigned long cflag)
|
||||
{
|
||||
long l;
|
||||
int ret = 0, i;
|
||||
char *m = NULL, mlch = ' ';
|
||||
int nmindent = 0;
|
||||
X509_CINF *ci;
|
||||
ASN1_INTEGER *bs;
|
||||
EVP_PKEY *pkey = NULL;
|
||||
const char *neg;
|
||||
|
||||
if((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
|
||||
mlch = '\n';
|
||||
nmindent = 12;
|
||||
}
|
||||
if ((nmflags & XN_FLAG_SEP_MASK) == XN_FLAG_SEP_MULTILINE) {
|
||||
mlch = '\n';
|
||||
nmindent = 12;
|
||||
}
|
||||
|
||||
if(nmflags == X509_FLAG_COMPAT)
|
||||
nmindent = 16;
|
||||
if (nmflags == X509_FLAG_COMPAT)
|
||||
nmindent = 16;
|
||||
|
||||
ci=x->cert_info;
|
||||
if(!(cflag & X509_FLAG_NO_HEADER))
|
||||
{
|
||||
if (BIO_write(bp,"Certificate:\n",13) <= 0) goto err;
|
||||
if (BIO_write(bp," Data:\n",10) <= 0) goto err;
|
||||
}
|
||||
if(!(cflag & X509_FLAG_NO_VERSION))
|
||||
{
|
||||
l=X509_get_version(x);
|
||||
if (BIO_printf(bp,"%8sVersion: %lu (0x%lx)\n","",l+1,l) <= 0) goto err;
|
||||
}
|
||||
if(!(cflag & X509_FLAG_NO_SERIAL))
|
||||
{
|
||||
ci = x->cert_info;
|
||||
if (!(cflag & X509_FLAG_NO_HEADER)) {
|
||||
if (BIO_write(bp, "Certificate:\n", 13) <= 0)
|
||||
goto err;
|
||||
if (BIO_write(bp, " Data:\n", 10) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (!(cflag & X509_FLAG_NO_VERSION)) {
|
||||
l = X509_get_version(x);
|
||||
if (BIO_printf(bp, "%8sVersion: %lu (0x%lx)\n", "", l + 1, l) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (!(cflag & X509_FLAG_NO_SERIAL)) {
|
||||
|
||||
if (BIO_write(bp," Serial Number:",22) <= 0) goto err;
|
||||
if (BIO_write(bp, " Serial Number:", 22) <= 0)
|
||||
goto err;
|
||||
|
||||
bs=X509_get_serialNumber(x);
|
||||
if (bs->length <= (int)sizeof(long))
|
||||
{
|
||||
l=ASN1_INTEGER_get(bs);
|
||||
if (bs->type == V_ASN1_NEG_INTEGER)
|
||||
{
|
||||
l= -l;
|
||||
neg="-";
|
||||
}
|
||||
else
|
||||
neg="";
|
||||
if (BIO_printf(bp," %s%lu (%s0x%lx)\n",neg,l,neg,l) <= 0)
|
||||
goto err;
|
||||
}
|
||||
else
|
||||
{
|
||||
neg=(bs->type == V_ASN1_NEG_INTEGER)?" (Negative)":"";
|
||||
if (BIO_printf(bp,"\n%12s%s","",neg) <= 0) goto err;
|
||||
bs = X509_get_serialNumber(x);
|
||||
if (bs->length <= (int)sizeof(long)) {
|
||||
l = ASN1_INTEGER_get(bs);
|
||||
if (bs->type == V_ASN1_NEG_INTEGER) {
|
||||
l = -l;
|
||||
neg = "-";
|
||||
} else
|
||||
neg = "";
|
||||
if (BIO_printf(bp, " %s%lu (%s0x%lx)\n", neg, l, neg, l) <= 0)
|
||||
goto err;
|
||||
} else {
|
||||
neg = (bs->type == V_ASN1_NEG_INTEGER) ? " (Negative)" : "";
|
||||
if (BIO_printf(bp, "\n%12s%s", "", neg) <= 0)
|
||||
goto err;
|
||||
|
||||
for (i=0; i<bs->length; i++)
|
||||
{
|
||||
if (BIO_printf(bp,"%02x%c",bs->data[i],
|
||||
((i+1 == bs->length)?'\n':':')) <= 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
for (i = 0; i < bs->length; i++) {
|
||||
if (BIO_printf(bp, "%02x%c", bs->data[i],
|
||||
((i + 1 == bs->length) ? '\n' : ':')) <= 0)
|
||||
goto err;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
if(!(cflag & X509_FLAG_NO_SIGNAME))
|
||||
{
|
||||
if(X509_signature_print(bp, x->sig_alg, NULL) <= 0)
|
||||
goto err;
|
||||
if (!(cflag & X509_FLAG_NO_SIGNAME)) {
|
||||
if (X509_signature_print(bp, ci->signature, NULL) <= 0)
|
||||
goto err;
|
||||
#if 0
|
||||
if (BIO_printf(bp,"%8sSignature Algorithm: ","") <= 0)
|
||||
goto err;
|
||||
if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
|
||||
goto err;
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
goto err;
|
||||
if (BIO_printf(bp, "%8sSignature Algorithm: ", "") <= 0)
|
||||
goto err;
|
||||
if (i2a_ASN1_OBJECT(bp, ci->signature->algorithm) <= 0)
|
||||
goto err;
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
goto err;
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
if(!(cflag & X509_FLAG_NO_ISSUER))
|
||||
{
|
||||
if (BIO_printf(bp," Issuer:%c",mlch) <= 0) goto err;
|
||||
if (X509_NAME_print_ex(bp,X509_get_issuer_name(x),nmindent, nmflags) < 0) goto err;
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto err;
|
||||
}
|
||||
if(!(cflag & X509_FLAG_NO_VALIDITY))
|
||||
{
|
||||
if (BIO_write(bp," Validity\n",17) <= 0) goto err;
|
||||
if (BIO_write(bp," Not Before: ",24) <= 0) goto err;
|
||||
if (!ASN1_TIME_print(bp,X509_get_notBefore(x))) goto err;
|
||||
if (BIO_write(bp,"\n Not After : ",25) <= 0) goto err;
|
||||
if (!ASN1_TIME_print(bp,X509_get_notAfter(x))) goto err;
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto err;
|
||||
}
|
||||
if(!(cflag & X509_FLAG_NO_SUBJECT))
|
||||
{
|
||||
if (BIO_printf(bp," Subject:%c",mlch) <= 0) goto err;
|
||||
if (X509_NAME_print_ex(bp,X509_get_subject_name(x),nmindent, nmflags) < 0) goto err;
|
||||
if (BIO_write(bp,"\n",1) <= 0) goto err;
|
||||
}
|
||||
if(!(cflag & X509_FLAG_NO_PUBKEY))
|
||||
{
|
||||
if (BIO_write(bp," Subject Public Key Info:\n",33) <= 0)
|
||||
goto err;
|
||||
if (BIO_printf(bp,"%12sPublic Key Algorithm: ","") <= 0)
|
||||
goto err;
|
||||
if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
|
||||
goto err;
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
goto err;
|
||||
if (!(cflag & X509_FLAG_NO_ISSUER)) {
|
||||
if (BIO_printf(bp, " Issuer:%c", mlch) <= 0)
|
||||
goto err;
|
||||
if (X509_NAME_print_ex(bp, X509_get_issuer_name(x), nmindent, nmflags)
|
||||
< 0)
|
||||
goto err;
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (!(cflag & X509_FLAG_NO_VALIDITY)) {
|
||||
if (BIO_write(bp, " Validity\n", 17) <= 0)
|
||||
goto err;
|
||||
if (BIO_write(bp, " Not Before: ", 24) <= 0)
|
||||
goto err;
|
||||
if (!ASN1_TIME_print(bp, X509_get_notBefore(x)))
|
||||
goto err;
|
||||
if (BIO_write(bp, "\n Not After : ", 25) <= 0)
|
||||
goto err;
|
||||
if (!ASN1_TIME_print(bp, X509_get_notAfter(x)))
|
||||
goto err;
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (!(cflag & X509_FLAG_NO_SUBJECT)) {
|
||||
if (BIO_printf(bp, " Subject:%c", mlch) <= 0)
|
||||
goto err;
|
||||
if (X509_NAME_print_ex
|
||||
(bp, X509_get_subject_name(x), nmindent, nmflags) < 0)
|
||||
goto err;
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (!(cflag & X509_FLAG_NO_PUBKEY)) {
|
||||
if (BIO_write(bp, " Subject Public Key Info:\n", 33) <= 0)
|
||||
goto err;
|
||||
if (BIO_printf(bp, "%12sPublic Key Algorithm: ", "") <= 0)
|
||||
goto err;
|
||||
if (i2a_ASN1_OBJECT(bp, ci->key->algor->algorithm) <= 0)
|
||||
goto err;
|
||||
if (BIO_puts(bp, "\n") <= 0)
|
||||
goto err;
|
||||
|
||||
pkey=X509_get_pubkey(x);
|
||||
if (pkey == NULL)
|
||||
{
|
||||
BIO_printf(bp,"%12sUnable to load Public Key\n","");
|
||||
ERR_print_errors(bp);
|
||||
}
|
||||
else
|
||||
{
|
||||
EVP_PKEY_print_public(bp, pkey, 16, NULL);
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
}
|
||||
pkey = X509_get_pubkey(x);
|
||||
if (pkey == NULL) {
|
||||
BIO_printf(bp, "%12sUnable to load Public Key\n", "");
|
||||
ERR_print_errors(bp);
|
||||
} else {
|
||||
EVP_PKEY_print_public(bp, pkey, 16, NULL);
|
||||
EVP_PKEY_free(pkey);
|
||||
}
|
||||
}
|
||||
|
||||
if (!(cflag & X509_FLAG_NO_EXTENSIONS))
|
||||
X509V3_extensions_print(bp, "X509v3 extensions",
|
||||
ci->extensions, cflag, 8);
|
||||
if (!(cflag & X509_FLAG_NO_EXTENSIONS))
|
||||
X509V3_extensions_print(bp, "X509v3 extensions",
|
||||
ci->extensions, cflag, 8);
|
||||
|
||||
if(!(cflag & X509_FLAG_NO_SIGDUMP))
|
||||
{
|
||||
if(X509_signature_print(bp, x->sig_alg, x->signature) <= 0) goto err;
|
||||
}
|
||||
if(!(cflag & X509_FLAG_NO_AUX))
|
||||
{
|
||||
if (!X509_CERT_AUX_print(bp, x->aux, 0)) goto err;
|
||||
}
|
||||
ret=1;
|
||||
err:
|
||||
if (m != NULL) OPENSSL_free(m);
|
||||
return(ret);
|
||||
}
|
||||
if (!(cflag & X509_FLAG_NO_SIGDUMP)) {
|
||||
if (X509_signature_print(bp, x->sig_alg, x->signature) <= 0)
|
||||
goto err;
|
||||
}
|
||||
if (!(cflag & X509_FLAG_NO_AUX)) {
|
||||
if (!X509_CERT_AUX_print(bp, x->aux, 0))
|
||||
goto err;
|
||||
}
|
||||
ret = 1;
|
||||
err:
|
||||
if (m != NULL)
|
||||
OPENSSL_free(m);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
int X509_ocspid_print (BIO *bp, X509 *x)
|
||||
{
|
||||
unsigned char *der=NULL ;
|
||||
unsigned char *dertmp;
|
||||
int derlen;
|
||||
int i;
|
||||
unsigned char SHA1md[SHA_DIGEST_LENGTH];
|
||||
int X509_ocspid_print(BIO *bp, X509 *x)
|
||||
{
|
||||
unsigned char *der = NULL;
|
||||
unsigned char *dertmp;
|
||||
int derlen;
|
||||
int i;
|
||||
unsigned char SHA1md[SHA_DIGEST_LENGTH];
|
||||
|
||||
/* display the hash of the subject as it would appear
|
||||
in OCSP requests */
|
||||
if (BIO_printf(bp," Subject OCSP hash: ") <= 0)
|
||||
goto err;
|
||||
derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
|
||||
if ((der = dertmp = (unsigned char *)OPENSSL_malloc (derlen)) == NULL)
|
||||
goto err;
|
||||
i2d_X509_NAME(x->cert_info->subject, &dertmp);
|
||||
/*
|
||||
* display the hash of the subject as it would appear in OCSP requests
|
||||
*/
|
||||
if (BIO_printf(bp, " Subject OCSP hash: ") <= 0)
|
||||
goto err;
|
||||
derlen = i2d_X509_NAME(x->cert_info->subject, NULL);
|
||||
if ((der = dertmp = (unsigned char *)OPENSSL_malloc(derlen)) == NULL)
|
||||
goto err;
|
||||
i2d_X509_NAME(x->cert_info->subject, &dertmp);
|
||||
|
||||
if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
|
||||
goto err;
|
||||
for (i=0; i < SHA_DIGEST_LENGTH; i++)
|
||||
{
|
||||
if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0) goto err;
|
||||
}
|
||||
OPENSSL_free (der);
|
||||
der=NULL;
|
||||
if (!EVP_Digest(der, derlen, SHA1md, NULL, EVP_sha1(), NULL))
|
||||
goto err;
|
||||
for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
|
||||
if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
|
||||
goto err;
|
||||
}
|
||||
OPENSSL_free(der);
|
||||
der = NULL;
|
||||
|
||||
/* display the hash of the public key as it would appear
|
||||
in OCSP requests */
|
||||
if (BIO_printf(bp,"\n Public key OCSP hash: ") <= 0)
|
||||
goto err;
|
||||
/*
|
||||
* display the hash of the public key as it would appear in OCSP requests
|
||||
*/
|
||||
if (BIO_printf(bp, "\n Public key OCSP hash: ") <= 0)
|
||||
goto err;
|
||||
|
||||
if (!EVP_Digest(x->cert_info->key->public_key->data,
|
||||
x->cert_info->key->public_key->length,
|
||||
SHA1md, NULL, EVP_sha1(), NULL))
|
||||
goto err;
|
||||
for (i=0; i < SHA_DIGEST_LENGTH; i++)
|
||||
{
|
||||
if (BIO_printf(bp,"%02X",SHA1md[i]) <= 0)
|
||||
goto err;
|
||||
}
|
||||
BIO_printf(bp,"\n");
|
||||
if (!EVP_Digest(x->cert_info->key->public_key->data,
|
||||
x->cert_info->key->public_key->length,
|
||||
SHA1md, NULL, EVP_sha1(), NULL))
|
||||
goto err;
|
||||
for (i = 0; i < SHA_DIGEST_LENGTH; i++) {
|
||||
if (BIO_printf(bp, "%02X", SHA1md[i]) <= 0)
|
||||
goto err;
|
||||
}
|
||||
BIO_printf(bp, "\n");
|
||||
|
||||
return (1);
|
||||
err:
|
||||
if (der != NULL) OPENSSL_free(der);
|
||||
return(0);
|
||||
}
|
||||
return (1);
|
||||
err:
|
||||
if (der != NULL)
|
||||
OPENSSL_free(der);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int X509_signature_dump(BIO *bp, const ASN1_STRING *sig, int indent)
|
||||
{
|
||||
const unsigned char *s;
|
||||
int i, n;
|
||||
const unsigned char *s;
|
||||
int i, n;
|
||||
|
||||
n=sig->length;
|
||||
s=sig->data;
|
||||
for (i=0; i<n; i++)
|
||||
{
|
||||
if ((i%18) == 0)
|
||||
{
|
||||
if (BIO_write(bp,"\n",1) <= 0) return 0;
|
||||
if (BIO_indent(bp, indent, indent) <= 0) return 0;
|
||||
}
|
||||
if (BIO_printf(bp,"%02x%s",s[i],
|
||||
((i+1) == n)?"":":") <= 0) return 0;
|
||||
}
|
||||
if (BIO_write(bp,"\n",1) != 1) return 0;
|
||||
n = sig->length;
|
||||
s = sig->data;
|
||||
for (i = 0; i < n; i++) {
|
||||
if ((i % 18) == 0) {
|
||||
if (BIO_write(bp, "\n", 1) <= 0)
|
||||
return 0;
|
||||
if (BIO_indent(bp, indent, indent) <= 0)
|
||||
return 0;
|
||||
}
|
||||
if (BIO_printf(bp, "%02x%s", s[i], ((i + 1) == n) ? "" : ":") <= 0)
|
||||
return 0;
|
||||
}
|
||||
if (BIO_write(bp, "\n", 1) != 1)
|
||||
return 0;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int X509_signature_print(BIO *bp, X509_ALGOR *sigalg, ASN1_STRING *sig)
|
||||
{
|
||||
int sig_nid;
|
||||
if (BIO_puts(bp," Signature Algorithm: ") <= 0) return 0;
|
||||
if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0) return 0;
|
||||
int sig_nid;
|
||||
if (BIO_puts(bp, " Signature Algorithm: ") <= 0)
|
||||
return 0;
|
||||
if (i2a_ASN1_OBJECT(bp, sigalg->algorithm) <= 0)
|
||||
return 0;
|
||||
|
||||
sig_nid = OBJ_obj2nid(sigalg->algorithm);
|
||||
if (sig_nid != NID_undef)
|
||||
{
|
||||
int pkey_nid, dig_nid;
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid))
|
||||
{
|
||||
ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
|
||||
if (ameth && ameth->sig_print)
|
||||
return ameth->sig_print(bp, sigalg, sig, 9, 0);
|
||||
}
|
||||
}
|
||||
if (sig)
|
||||
return X509_signature_dump(bp, sig, 9);
|
||||
else if (BIO_puts(bp, "\n") <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
sig_nid = OBJ_obj2nid(sigalg->algorithm);
|
||||
if (sig_nid != NID_undef) {
|
||||
int pkey_nid, dig_nid;
|
||||
const EVP_PKEY_ASN1_METHOD *ameth;
|
||||
if (OBJ_find_sigid_algs(sig_nid, &dig_nid, &pkey_nid)) {
|
||||
ameth = EVP_PKEY_asn1_find(NULL, pkey_nid);
|
||||
if (ameth && ameth->sig_print)
|
||||
return ameth->sig_print(bp, sigalg, sig, 9, 0);
|
||||
}
|
||||
}
|
||||
if (sig)
|
||||
return X509_signature_dump(bp, sig, 9);
|
||||
else if (BIO_puts(bp, "\n") <= 0)
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int ASN1_STRING_print(BIO *bp, const ASN1_STRING *v)
|
||||
{
|
||||
int i,n;
|
||||
char buf[80];
|
||||
const char *p;
|
||||
{
|
||||
int i, n;
|
||||
char buf[80];
|
||||
const char *p;
|
||||
|
||||
if (v == NULL) return(0);
|
||||
n=0;
|
||||
p=(const char *)v->data;
|
||||
for (i=0; i<v->length; i++)
|
||||
{
|
||||
if ((p[i] > '~') || ((p[i] < ' ') &&
|
||||
(p[i] != '\n') && (p[i] != '\r')))
|
||||
buf[n]='.';
|
||||
else
|
||||
buf[n]=p[i];
|
||||
n++;
|
||||
if (n >= 80)
|
||||
{
|
||||
if (BIO_write(bp,buf,n) <= 0)
|
||||
return(0);
|
||||
n=0;
|
||||
}
|
||||
}
|
||||
if (n > 0)
|
||||
if (BIO_write(bp,buf,n) <= 0)
|
||||
return(0);
|
||||
return(1);
|
||||
}
|
||||
if (v == NULL)
|
||||
return (0);
|
||||
n = 0;
|
||||
p = (const char *)v->data;
|
||||
for (i = 0; i < v->length; i++) {
|
||||
if ((p[i] > '~') || ((p[i] < ' ') &&
|
||||
(p[i] != '\n') && (p[i] != '\r')))
|
||||
buf[n] = '.';
|
||||
else
|
||||
buf[n] = p[i];
|
||||
n++;
|
||||
if (n >= 80) {
|
||||
if (BIO_write(bp, buf, n) <= 0)
|
||||
return (0);
|
||||
n = 0;
|
||||
}
|
||||
}
|
||||
if (n > 0)
|
||||
if (BIO_write(bp, buf, n) <= 0)
|
||||
return (0);
|
||||
return (1);
|
||||
}
|
||||
|
||||
int ASN1_TIME_print(BIO *bp, const ASN1_TIME *tm)
|
||||
{
|
||||
if(tm->type == V_ASN1_UTCTIME) return ASN1_UTCTIME_print(bp, tm);
|
||||
if(tm->type == V_ASN1_GENERALIZEDTIME)
|
||||
return ASN1_GENERALIZEDTIME_print(bp, tm);
|
||||
BIO_write(bp,"Bad time value",14);
|
||||
return(0);
|
||||
if (tm->type == V_ASN1_UTCTIME)
|
||||
return ASN1_UTCTIME_print(bp, tm);
|
||||
if (tm->type == V_ASN1_GENERALIZEDTIME)
|
||||
return ASN1_GENERALIZEDTIME_print(bp, tm);
|
||||
BIO_write(bp, "Bad time value", 14);
|
||||
return (0);
|
||||
}
|
||||
|
||||
static const char *mon[12]=
|
||||
{
|
||||
"Jan","Feb","Mar","Apr","May","Jun",
|
||||
"Jul","Aug","Sep","Oct","Nov","Dec"
|
||||
};
|
||||
static const char *mon[12] = {
|
||||
"Jan", "Feb", "Mar", "Apr", "May", "Jun",
|
||||
"Jul", "Aug", "Sep", "Oct", "Nov", "Dec"
|
||||
};
|
||||
|
||||
int ASN1_GENERALIZEDTIME_print(BIO *bp, const ASN1_GENERALIZEDTIME *tm)
|
||||
{
|
||||
char *v;
|
||||
int gmt=0;
|
||||
int i;
|
||||
int y=0,M=0,d=0,h=0,m=0,s=0;
|
||||
char *f = NULL;
|
||||
int f_len = 0;
|
||||
{
|
||||
char *v;
|
||||
int gmt = 0;
|
||||
int i;
|
||||
int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
|
||||
char *f = NULL;
|
||||
int f_len = 0;
|
||||
|
||||
i=tm->length;
|
||||
v=(char *)tm->data;
|
||||
i = tm->length;
|
||||
v = (char *)tm->data;
|
||||
|
||||
if (i < 12) goto err;
|
||||
if (v[i-1] == 'Z') gmt=1;
|
||||
for (i=0; i<12; i++)
|
||||
if ((v[i] > '9') || (v[i] < '0')) goto err;
|
||||
y= (v[0]-'0')*1000+(v[1]-'0')*100 + (v[2]-'0')*10+(v[3]-'0');
|
||||
M= (v[4]-'0')*10+(v[5]-'0');
|
||||
if ((M > 12) || (M < 1)) goto err;
|
||||
d= (v[6]-'0')*10+(v[7]-'0');
|
||||
h= (v[8]-'0')*10+(v[9]-'0');
|
||||
m= (v[10]-'0')*10+(v[11]-'0');
|
||||
if (tm->length >= 14 &&
|
||||
(v[12] >= '0') && (v[12] <= '9') &&
|
||||
(v[13] >= '0') && (v[13] <= '9'))
|
||||
{
|
||||
s= (v[12]-'0')*10+(v[13]-'0');
|
||||
/* Check for fractions of seconds. */
|
||||
if (tm->length >= 15 && v[14] == '.')
|
||||
{
|
||||
int l = tm->length;
|
||||
f = &v[14]; /* The decimal point. */
|
||||
f_len = 1;
|
||||
while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
|
||||
++f_len;
|
||||
}
|
||||
}
|
||||
if (i < 12)
|
||||
goto err;
|
||||
if (v[i - 1] == 'Z')
|
||||
gmt = 1;
|
||||
for (i = 0; i < 12; i++)
|
||||
if ((v[i] > '9') || (v[i] < '0'))
|
||||
goto err;
|
||||
y = (v[0] - '0') * 1000 + (v[1] - '0') * 100
|
||||
+ (v[2] - '0') * 10 + (v[3] - '0');
|
||||
M = (v[4] - '0') * 10 + (v[5] - '0');
|
||||
if ((M > 12) || (M < 1))
|
||||
goto err;
|
||||
d = (v[6] - '0') * 10 + (v[7] - '0');
|
||||
h = (v[8] - '0') * 10 + (v[9] - '0');
|
||||
m = (v[10] - '0') * 10 + (v[11] - '0');
|
||||
if (tm->length >= 14 &&
|
||||
(v[12] >= '0') && (v[12] <= '9') &&
|
||||
(v[13] >= '0') && (v[13] <= '9')) {
|
||||
s = (v[12] - '0') * 10 + (v[13] - '0');
|
||||
/* Check for fractions of seconds. */
|
||||
if (tm->length >= 15 && v[14] == '.') {
|
||||
int l = tm->length;
|
||||
f = &v[14]; /* The decimal point. */
|
||||
f_len = 1;
|
||||
while (14 + f_len < l && f[f_len] >= '0' && f[f_len] <= '9')
|
||||
++f_len;
|
||||
}
|
||||
}
|
||||
|
||||
if (BIO_printf(bp,"%s %2d %02d:%02d:%02d%.*s %d%s",
|
||||
mon[M-1],d,h,m,s,f_len,f,y,(gmt)?" GMT":"") <= 0)
|
||||
return(0);
|
||||
else
|
||||
return(1);
|
||||
err:
|
||||
BIO_write(bp,"Bad time value",14);
|
||||
return(0);
|
||||
}
|
||||
if (BIO_printf(bp, "%s %2d %02d:%02d:%02d%.*s %d%s",
|
||||
mon[M - 1], d, h, m, s, f_len, f, y,
|
||||
(gmt) ? " GMT" : "") <= 0)
|
||||
return (0);
|
||||
else
|
||||
return (1);
|
||||
err:
|
||||
BIO_write(bp, "Bad time value", 14);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int ASN1_UTCTIME_print(BIO *bp, const ASN1_UTCTIME *tm)
|
||||
{
|
||||
const char *v;
|
||||
int gmt=0;
|
||||
int i;
|
||||
int y=0,M=0,d=0,h=0,m=0,s=0;
|
||||
{
|
||||
const char *v;
|
||||
int gmt = 0;
|
||||
int i;
|
||||
int y = 0, M = 0, d = 0, h = 0, m = 0, s = 0;
|
||||
|
||||
i=tm->length;
|
||||
v=(const char *)tm->data;
|
||||
i = tm->length;
|
||||
v = (const char *)tm->data;
|
||||
|
||||
if (i < 10) goto err;
|
||||
if (v[i-1] == 'Z') gmt=1;
|
||||
for (i=0; i<10; i++)
|
||||
if ((v[i] > '9') || (v[i] < '0')) goto err;
|
||||
y= (v[0]-'0')*10+(v[1]-'0');
|
||||
if (y < 50) y+=100;
|
||||
M= (v[2]-'0')*10+(v[3]-'0');
|
||||
if ((M > 12) || (M < 1)) goto err;
|
||||
d= (v[4]-'0')*10+(v[5]-'0');
|
||||
h= (v[6]-'0')*10+(v[7]-'0');
|
||||
m= (v[8]-'0')*10+(v[9]-'0');
|
||||
if (tm->length >=12 &&
|
||||
(v[10] >= '0') && (v[10] <= '9') &&
|
||||
(v[11] >= '0') && (v[11] <= '9'))
|
||||
s= (v[10]-'0')*10+(v[11]-'0');
|
||||
if (i < 10)
|
||||
goto err;
|
||||
if (v[i - 1] == 'Z')
|
||||
gmt = 1;
|
||||
for (i = 0; i < 10; i++)
|
||||
if ((v[i] > '9') || (v[i] < '0'))
|
||||
goto err;
|
||||
y = (v[0] - '0') * 10 + (v[1] - '0');
|
||||
if (y < 50)
|
||||
y += 100;
|
||||
M = (v[2] - '0') * 10 + (v[3] - '0');
|
||||
if ((M > 12) || (M < 1))
|
||||
goto err;
|
||||
d = (v[4] - '0') * 10 + (v[5] - '0');
|
||||
h = (v[6] - '0') * 10 + (v[7] - '0');
|
||||
m = (v[8] - '0') * 10 + (v[9] - '0');
|
||||
if (tm->length >= 12 &&
|
||||
(v[10] >= '0') && (v[10] <= '9') && (v[11] >= '0') && (v[11] <= '9'))
|
||||
s = (v[10] - '0') * 10 + (v[11] - '0');
|
||||
|
||||
if (BIO_printf(bp,"%s %2d %02d:%02d:%02d %d%s",
|
||||
mon[M-1],d,h,m,s,y+1900,(gmt)?" GMT":"") <= 0)
|
||||
return(0);
|
||||
else
|
||||
return(1);
|
||||
err:
|
||||
BIO_write(bp,"Bad time value",14);
|
||||
return(0);
|
||||
}
|
||||
if (BIO_printf(bp, "%s %2d %02d:%02d:%02d %d%s",
|
||||
mon[M - 1], d, h, m, s, y + 1900,
|
||||
(gmt) ? " GMT" : "") <= 0)
|
||||
return (0);
|
||||
else
|
||||
return (1);
|
||||
err:
|
||||
BIO_write(bp, "Bad time value", 14);
|
||||
return (0);
|
||||
}
|
||||
|
||||
int X509_NAME_print(BIO *bp, X509_NAME *name, int obase)
|
||||
{
|
||||
char *s,*c,*b;
|
||||
int ret=0,l,i;
|
||||
{
|
||||
char *s, *c, *b;
|
||||
int ret = 0, l, i;
|
||||
|
||||
l=80-2-obase;
|
||||
l = 80 - 2 - obase;
|
||||
|
||||
b=X509_NAME_oneline(name,NULL,0);
|
||||
if (!*b)
|
||||
{
|
||||
OPENSSL_free(b);
|
||||
return 1;
|
||||
}
|
||||
s=b+1; /* skip the first slash */
|
||||
b = X509_NAME_oneline(name, NULL, 0);
|
||||
if (!b)
|
||||
return 0;
|
||||
if (!*b) {
|
||||
OPENSSL_free(b);
|
||||
return 1;
|
||||
}
|
||||
s = b + 1; /* skip the first slash */
|
||||
|
||||
c=s;
|
||||
for (;;)
|
||||
{
|
||||
c = s;
|
||||
for (;;) {
|
||||
#ifndef CHARSET_EBCDIC
|
||||
if ( ((*s == '/') &&
|
||||
((s[1] >= 'A') && (s[1] <= 'Z') && (
|
||||
(s[2] == '=') ||
|
||||
((s[2] >= 'A') && (s[2] <= 'Z') &&
|
||||
(s[3] == '='))
|
||||
))) ||
|
||||
(*s == '\0'))
|
||||
if (((*s == '/') &&
|
||||
((s[1] >= 'A') && (s[1] <= 'Z') && ((s[2] == '=') ||
|
||||
((s[2] >= 'A')
|
||||
&& (s[2] <= 'Z')
|
||||
&& (s[3] == '='))
|
||||
))) || (*s == '\0'))
|
||||
#else
|
||||
if ( ((*s == '/') &&
|
||||
(isupper(s[1]) && (
|
||||
(s[2] == '=') ||
|
||||
(isupper(s[2]) &&
|
||||
(s[3] == '='))
|
||||
))) ||
|
||||
(*s == '\0'))
|
||||
if (((*s == '/') &&
|
||||
(isupper(s[1]) && ((s[2] == '=') ||
|
||||
(isupper(s[2]) && (s[3] == '='))
|
||||
))) || (*s == '\0'))
|
||||
#endif
|
||||
{
|
||||
i=s-c;
|
||||
if (BIO_write(bp,c,i) != i) goto err;
|
||||
c=s+1; /* skip following slash */
|
||||
if (*s != '\0')
|
||||
{
|
||||
if (BIO_write(bp,", ",2) != 2) goto err;
|
||||
}
|
||||
l--;
|
||||
}
|
||||
if (*s == '\0') break;
|
||||
s++;
|
||||
l--;
|
||||
}
|
||||
|
||||
ret=1;
|
||||
if (0)
|
||||
{
|
||||
err:
|
||||
X509err(X509_F_X509_NAME_PRINT,ERR_R_BUF_LIB);
|
||||
}
|
||||
OPENSSL_free(b);
|
||||
return(ret);
|
||||
}
|
||||
{
|
||||
i = s - c;
|
||||
if (BIO_write(bp, c, i) != i)
|
||||
goto err;
|
||||
c = s + 1; /* skip following slash */
|
||||
if (*s != '\0') {
|
||||
if (BIO_write(bp, ", ", 2) != 2)
|
||||
goto err;
|
||||
}
|
||||
l--;
|
||||
}
|
||||
if (*s == '\0')
|
||||
break;
|
||||
s++;
|
||||
l--;
|
||||
}
|
||||
|
||||
ret = 1;
|
||||
if (0) {
|
||||
err:
|
||||
X509err(X509_F_X509_NAME_PRINT, ERR_R_BUF_LIB);
|
||||
}
|
||||
OPENSSL_free(b);
|
||||
return (ret);
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* t_x509a.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 1999.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 1999.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 1999 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -62,49 +63,53 @@
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
/* X509_CERT_AUX and string set routines
|
||||
/*
|
||||
* X509_CERT_AUX and string set routines
|
||||
*/
|
||||
|
||||
int X509_CERT_AUX_print(BIO *out, X509_CERT_AUX *aux, int indent)
|
||||
{
|
||||
char oidstr[80], first;
|
||||
int i;
|
||||
if(!aux) return 1;
|
||||
if(aux->trust) {
|
||||
first = 1;
|
||||
BIO_printf(out, "%*sTrusted Uses:\n%*s",
|
||||
indent, "", indent + 2, "");
|
||||
for(i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
|
||||
if(!first) BIO_puts(out, ", ");
|
||||
else first = 0;
|
||||
OBJ_obj2txt(oidstr, sizeof oidstr,
|
||||
sk_ASN1_OBJECT_value(aux->trust, i), 0);
|
||||
BIO_puts(out, oidstr);
|
||||
}
|
||||
BIO_puts(out, "\n");
|
||||
} else BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
|
||||
if(aux->reject) {
|
||||
first = 1;
|
||||
BIO_printf(out, "%*sRejected Uses:\n%*s",
|
||||
indent, "", indent + 2, "");
|
||||
for(i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
|
||||
if(!first) BIO_puts(out, ", ");
|
||||
else first = 0;
|
||||
OBJ_obj2txt(oidstr, sizeof oidstr,
|
||||
sk_ASN1_OBJECT_value(aux->reject, i), 0);
|
||||
BIO_puts(out, oidstr);
|
||||
}
|
||||
BIO_puts(out, "\n");
|
||||
} else BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
|
||||
if(aux->alias) BIO_printf(out, "%*sAlias: %s\n", indent, "",
|
||||
aux->alias->data);
|
||||
if(aux->keyid) {
|
||||
BIO_printf(out, "%*sKey Id: ", indent, "");
|
||||
for(i = 0; i < aux->keyid->length; i++)
|
||||
BIO_printf(out, "%s%02X",
|
||||
i ? ":" : "",
|
||||
aux->keyid->data[i]);
|
||||
BIO_write(out,"\n",1);
|
||||
}
|
||||
return 1;
|
||||
char oidstr[80], first;
|
||||
int i;
|
||||
if (!aux)
|
||||
return 1;
|
||||
if (aux->trust) {
|
||||
first = 1;
|
||||
BIO_printf(out, "%*sTrusted Uses:\n%*s", indent, "", indent + 2, "");
|
||||
for (i = 0; i < sk_ASN1_OBJECT_num(aux->trust); i++) {
|
||||
if (!first)
|
||||
BIO_puts(out, ", ");
|
||||
else
|
||||
first = 0;
|
||||
OBJ_obj2txt(oidstr, sizeof oidstr,
|
||||
sk_ASN1_OBJECT_value(aux->trust, i), 0);
|
||||
BIO_puts(out, oidstr);
|
||||
}
|
||||
BIO_puts(out, "\n");
|
||||
} else
|
||||
BIO_printf(out, "%*sNo Trusted Uses.\n", indent, "");
|
||||
if (aux->reject) {
|
||||
first = 1;
|
||||
BIO_printf(out, "%*sRejected Uses:\n%*s", indent, "", indent + 2, "");
|
||||
for (i = 0; i < sk_ASN1_OBJECT_num(aux->reject); i++) {
|
||||
if (!first)
|
||||
BIO_puts(out, ", ");
|
||||
else
|
||||
first = 0;
|
||||
OBJ_obj2txt(oidstr, sizeof oidstr,
|
||||
sk_ASN1_OBJECT_value(aux->reject, i), 0);
|
||||
BIO_puts(out, oidstr);
|
||||
}
|
||||
BIO_puts(out, "\n");
|
||||
} else
|
||||
BIO_printf(out, "%*sNo Rejected Uses.\n", indent, "");
|
||||
if (aux->alias)
|
||||
BIO_printf(out, "%*sAlias: %s\n", indent, "", aux->alias->data);
|
||||
if (aux->keyid) {
|
||||
BIO_printf(out, "%*sKey Id: ", indent, "");
|
||||
for (i = 0; i < aux->keyid->length; i++)
|
||||
BIO_printf(out, "%s%02X", i ? ":" : "", aux->keyid->data[i]);
|
||||
BIO_write(out, "\n", 1);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
/* tasn_fre.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2000.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2000.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -56,211 +57,193 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/objects.h>
|
||||
|
||||
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine);
|
||||
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
int combine);
|
||||
|
||||
/* Free up an ASN1 structure */
|
||||
|
||||
void ASN1_item_free(ASN1_VALUE *val, const ASN1_ITEM *it)
|
||||
{
|
||||
asn1_item_combine_free(&val, it, 0);
|
||||
}
|
||||
{
|
||||
asn1_item_combine_free(&val, it, 0);
|
||||
}
|
||||
|
||||
void ASN1_item_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
asn1_item_combine_free(pval, it, 0);
|
||||
}
|
||||
{
|
||||
asn1_item_combine_free(pval, it, 0);
|
||||
}
|
||||
|
||||
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it, int combine)
|
||||
{
|
||||
const ASN1_TEMPLATE *tt = NULL, *seqtt;
|
||||
const ASN1_EXTERN_FUNCS *ef;
|
||||
const ASN1_COMPAT_FUNCS *cf;
|
||||
const ASN1_AUX *aux = it->funcs;
|
||||
ASN1_aux_cb *asn1_cb;
|
||||
int i;
|
||||
if (!pval)
|
||||
return;
|
||||
if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
|
||||
return;
|
||||
if (aux && aux->asn1_cb)
|
||||
asn1_cb = aux->asn1_cb;
|
||||
else
|
||||
asn1_cb = 0;
|
||||
static void asn1_item_combine_free(ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
int combine)
|
||||
{
|
||||
const ASN1_TEMPLATE *tt = NULL, *seqtt;
|
||||
const ASN1_EXTERN_FUNCS *ef;
|
||||
const ASN1_COMPAT_FUNCS *cf;
|
||||
const ASN1_AUX *aux = it->funcs;
|
||||
ASN1_aux_cb *asn1_cb;
|
||||
int i;
|
||||
if (!pval)
|
||||
return;
|
||||
if ((it->itype != ASN1_ITYPE_PRIMITIVE) && !*pval)
|
||||
return;
|
||||
if (aux && aux->asn1_cb)
|
||||
asn1_cb = aux->asn1_cb;
|
||||
else
|
||||
asn1_cb = 0;
|
||||
|
||||
switch(it->itype)
|
||||
{
|
||||
switch (it->itype) {
|
||||
|
||||
case ASN1_ITYPE_PRIMITIVE:
|
||||
if (it->templates)
|
||||
ASN1_template_free(pval, it->templates);
|
||||
else
|
||||
ASN1_primitive_free(pval, it);
|
||||
break;
|
||||
case ASN1_ITYPE_PRIMITIVE:
|
||||
if (it->templates)
|
||||
ASN1_template_free(pval, it->templates);
|
||||
else
|
||||
ASN1_primitive_free(pval, it);
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_MSTRING:
|
||||
ASN1_primitive_free(pval, it);
|
||||
break;
|
||||
case ASN1_ITYPE_MSTRING:
|
||||
ASN1_primitive_free(pval, it);
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_CHOICE:
|
||||
if (asn1_cb)
|
||||
{
|
||||
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
|
||||
if (i == 2)
|
||||
return;
|
||||
}
|
||||
i = asn1_get_choice_selector(pval, it);
|
||||
if ((i >= 0) && (i < it->tcount))
|
||||
{
|
||||
ASN1_VALUE **pchval;
|
||||
tt = it->templates + i;
|
||||
pchval = asn1_get_field_ptr(pval, tt);
|
||||
ASN1_template_free(pchval, tt);
|
||||
}
|
||||
if (asn1_cb)
|
||||
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
|
||||
if (!combine)
|
||||
{
|
||||
OPENSSL_free(*pval);
|
||||
*pval = NULL;
|
||||
}
|
||||
break;
|
||||
case ASN1_ITYPE_CHOICE:
|
||||
if (asn1_cb) {
|
||||
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
|
||||
if (i == 2)
|
||||
return;
|
||||
}
|
||||
i = asn1_get_choice_selector(pval, it);
|
||||
if ((i >= 0) && (i < it->tcount)) {
|
||||
ASN1_VALUE **pchval;
|
||||
tt = it->templates + i;
|
||||
pchval = asn1_get_field_ptr(pval, tt);
|
||||
ASN1_template_free(pchval, tt);
|
||||
}
|
||||
if (asn1_cb)
|
||||
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
|
||||
if (!combine) {
|
||||
OPENSSL_free(*pval);
|
||||
*pval = NULL;
|
||||
}
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_COMPAT:
|
||||
cf = it->funcs;
|
||||
if (cf && cf->asn1_free)
|
||||
cf->asn1_free(*pval);
|
||||
break;
|
||||
case ASN1_ITYPE_COMPAT:
|
||||
cf = it->funcs;
|
||||
if (cf && cf->asn1_free)
|
||||
cf->asn1_free(*pval);
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_EXTERN:
|
||||
ef = it->funcs;
|
||||
if (ef && ef->asn1_ex_free)
|
||||
ef->asn1_ex_free(pval, it);
|
||||
break;
|
||||
case ASN1_ITYPE_EXTERN:
|
||||
ef = it->funcs;
|
||||
if (ef && ef->asn1_ex_free)
|
||||
ef->asn1_ex_free(pval, it);
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_NDEF_SEQUENCE:
|
||||
case ASN1_ITYPE_SEQUENCE:
|
||||
if (asn1_do_lock(pval, -1, it) > 0)
|
||||
return;
|
||||
if (asn1_cb)
|
||||
{
|
||||
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
|
||||
if (i == 2)
|
||||
return;
|
||||
}
|
||||
asn1_enc_free(pval, it);
|
||||
/* If we free up as normal we will invalidate any
|
||||
* ANY DEFINED BY field and we wont be able to
|
||||
* determine the type of the field it defines. So
|
||||
* free up in reverse order.
|
||||
*/
|
||||
tt = it->templates + it->tcount - 1;
|
||||
for (i = 0; i < it->tcount; tt--, i++)
|
||||
{
|
||||
ASN1_VALUE **pseqval;
|
||||
seqtt = asn1_do_adb(pval, tt, 0);
|
||||
if (!seqtt)
|
||||
continue;
|
||||
pseqval = asn1_get_field_ptr(pval, seqtt);
|
||||
ASN1_template_free(pseqval, seqtt);
|
||||
}
|
||||
if (asn1_cb)
|
||||
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
|
||||
if (!combine)
|
||||
{
|
||||
OPENSSL_free(*pval);
|
||||
*pval = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
case ASN1_ITYPE_NDEF_SEQUENCE:
|
||||
case ASN1_ITYPE_SEQUENCE:
|
||||
if (asn1_do_lock(pval, -1, it) > 0)
|
||||
return;
|
||||
if (asn1_cb) {
|
||||
i = asn1_cb(ASN1_OP_FREE_PRE, pval, it, NULL);
|
||||
if (i == 2)
|
||||
return;
|
||||
}
|
||||
asn1_enc_free(pval, it);
|
||||
/*
|
||||
* If we free up as normal we will invalidate any ANY DEFINED BY
|
||||
* field and we wont be able to determine the type of the field it
|
||||
* defines. So free up in reverse order.
|
||||
*/
|
||||
tt = it->templates + it->tcount - 1;
|
||||
for (i = 0; i < it->tcount; tt--, i++) {
|
||||
ASN1_VALUE **pseqval;
|
||||
seqtt = asn1_do_adb(pval, tt, 0);
|
||||
if (!seqtt)
|
||||
continue;
|
||||
pseqval = asn1_get_field_ptr(pval, seqtt);
|
||||
ASN1_template_free(pseqval, seqtt);
|
||||
}
|
||||
if (asn1_cb)
|
||||
asn1_cb(ASN1_OP_FREE_POST, pval, it, NULL);
|
||||
if (!combine) {
|
||||
OPENSSL_free(*pval);
|
||||
*pval = NULL;
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void ASN1_template_free(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
|
||||
{
|
||||
int i;
|
||||
if (tt->flags & ASN1_TFLG_SK_MASK)
|
||||
{
|
||||
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
|
||||
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++)
|
||||
{
|
||||
ASN1_VALUE *vtmp;
|
||||
vtmp = sk_ASN1_VALUE_value(sk, i);
|
||||
asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item),
|
||||
0);
|
||||
}
|
||||
sk_ASN1_VALUE_free(sk);
|
||||
*pval = NULL;
|
||||
}
|
||||
else
|
||||
asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
|
||||
tt->flags & ASN1_TFLG_COMBINE);
|
||||
}
|
||||
{
|
||||
int i;
|
||||
if (tt->flags & ASN1_TFLG_SK_MASK) {
|
||||
STACK_OF(ASN1_VALUE) *sk = (STACK_OF(ASN1_VALUE) *)*pval;
|
||||
for (i = 0; i < sk_ASN1_VALUE_num(sk); i++) {
|
||||
ASN1_VALUE *vtmp;
|
||||
vtmp = sk_ASN1_VALUE_value(sk, i);
|
||||
asn1_item_combine_free(&vtmp, ASN1_ITEM_ptr(tt->item), 0);
|
||||
}
|
||||
sk_ASN1_VALUE_free(sk);
|
||||
*pval = NULL;
|
||||
} else
|
||||
asn1_item_combine_free(pval, ASN1_ITEM_ptr(tt->item),
|
||||
tt->flags & ASN1_TFLG_COMBINE);
|
||||
}
|
||||
|
||||
void ASN1_primitive_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
int utype;
|
||||
if (it)
|
||||
{
|
||||
const ASN1_PRIMITIVE_FUNCS *pf;
|
||||
pf = it->funcs;
|
||||
if (pf && pf->prim_free)
|
||||
{
|
||||
pf->prim_free(pval, it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
|
||||
if (!it)
|
||||
{
|
||||
ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
|
||||
utype = typ->type;
|
||||
pval = &typ->value.asn1_value;
|
||||
if (!*pval)
|
||||
return;
|
||||
}
|
||||
else if (it->itype == ASN1_ITYPE_MSTRING)
|
||||
{
|
||||
utype = -1;
|
||||
if (!*pval)
|
||||
return;
|
||||
}
|
||||
else
|
||||
{
|
||||
utype = it->utype;
|
||||
if ((utype != V_ASN1_BOOLEAN) && !*pval)
|
||||
return;
|
||||
}
|
||||
{
|
||||
int utype;
|
||||
if (it) {
|
||||
const ASN1_PRIMITIVE_FUNCS *pf;
|
||||
pf = it->funcs;
|
||||
if (pf && pf->prim_free) {
|
||||
pf->prim_free(pval, it);
|
||||
return;
|
||||
}
|
||||
}
|
||||
/* Special case: if 'it' is NULL free contents of ASN1_TYPE */
|
||||
if (!it) {
|
||||
ASN1_TYPE *typ = (ASN1_TYPE *)*pval;
|
||||
utype = typ->type;
|
||||
pval = &typ->value.asn1_value;
|
||||
if (!*pval)
|
||||
return;
|
||||
} else if (it->itype == ASN1_ITYPE_MSTRING) {
|
||||
utype = -1;
|
||||
if (!*pval)
|
||||
return;
|
||||
} else {
|
||||
utype = it->utype;
|
||||
if ((utype != V_ASN1_BOOLEAN) && !*pval)
|
||||
return;
|
||||
}
|
||||
|
||||
switch(utype)
|
||||
{
|
||||
case V_ASN1_OBJECT:
|
||||
ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
|
||||
break;
|
||||
switch (utype) {
|
||||
case V_ASN1_OBJECT:
|
||||
ASN1_OBJECT_free((ASN1_OBJECT *)*pval);
|
||||
break;
|
||||
|
||||
case V_ASN1_BOOLEAN:
|
||||
if (it)
|
||||
*(ASN1_BOOLEAN *)pval = it->size;
|
||||
else
|
||||
*(ASN1_BOOLEAN *)pval = -1;
|
||||
return;
|
||||
case V_ASN1_BOOLEAN:
|
||||
if (it)
|
||||
*(ASN1_BOOLEAN *)pval = it->size;
|
||||
else
|
||||
*(ASN1_BOOLEAN *)pval = -1;
|
||||
return;
|
||||
|
||||
case V_ASN1_NULL:
|
||||
break;
|
||||
case V_ASN1_NULL:
|
||||
break;
|
||||
|
||||
case V_ASN1_ANY:
|
||||
ASN1_primitive_free(pval, NULL);
|
||||
OPENSSL_free(*pval);
|
||||
break;
|
||||
case V_ASN1_ANY:
|
||||
ASN1_primitive_free(pval, NULL);
|
||||
OPENSSL_free(*pval);
|
||||
break;
|
||||
|
||||
default:
|
||||
ASN1_STRING_free((ASN1_STRING *)*pval);
|
||||
*pval = NULL;
|
||||
break;
|
||||
}
|
||||
*pval = NULL;
|
||||
}
|
||||
default:
|
||||
ASN1_STRING_free((ASN1_STRING *)*pval);
|
||||
*pval = NULL;
|
||||
break;
|
||||
}
|
||||
*pval = NULL;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* tasn_new.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2000.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2000.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -56,7 +57,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <openssl/asn1.h>
|
||||
#include <openssl/objects.h>
|
||||
@ -65,332 +65,317 @@
|
||||
#include <string.h>
|
||||
|
||||
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
int combine);
|
||||
int combine);
|
||||
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
|
||||
static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt);
|
||||
static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it);
|
||||
|
||||
ASN1_VALUE *ASN1_item_new(const ASN1_ITEM *it)
|
||||
{
|
||||
ASN1_VALUE *ret = NULL;
|
||||
if (ASN1_item_ex_new(&ret, it) > 0)
|
||||
return ret;
|
||||
return NULL;
|
||||
}
|
||||
{
|
||||
ASN1_VALUE *ret = NULL;
|
||||
if (ASN1_item_ex_new(&ret, it) > 0)
|
||||
return ret;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Allocate an ASN1 structure */
|
||||
|
||||
int ASN1_item_ex_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
return asn1_item_ex_combine_new(pval, it, 0);
|
||||
}
|
||||
{
|
||||
return asn1_item_ex_combine_new(pval, it, 0);
|
||||
}
|
||||
|
||||
static int asn1_item_ex_combine_new(ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
int combine)
|
||||
{
|
||||
const ASN1_TEMPLATE *tt = NULL;
|
||||
const ASN1_COMPAT_FUNCS *cf;
|
||||
const ASN1_EXTERN_FUNCS *ef;
|
||||
const ASN1_AUX *aux = it->funcs;
|
||||
ASN1_aux_cb *asn1_cb;
|
||||
ASN1_VALUE **pseqval;
|
||||
int i;
|
||||
if (aux && aux->asn1_cb)
|
||||
asn1_cb = aux->asn1_cb;
|
||||
else
|
||||
asn1_cb = 0;
|
||||
|
||||
if (!combine) *pval = NULL;
|
||||
int combine)
|
||||
{
|
||||
const ASN1_TEMPLATE *tt = NULL;
|
||||
const ASN1_COMPAT_FUNCS *cf;
|
||||
const ASN1_EXTERN_FUNCS *ef;
|
||||
const ASN1_AUX *aux = it->funcs;
|
||||
ASN1_aux_cb *asn1_cb;
|
||||
ASN1_VALUE **pseqval;
|
||||
int i;
|
||||
if (aux && aux->asn1_cb)
|
||||
asn1_cb = aux->asn1_cb;
|
||||
else
|
||||
asn1_cb = 0;
|
||||
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
if (it->sname)
|
||||
CRYPTO_push_info(it->sname);
|
||||
if (it->sname)
|
||||
CRYPTO_push_info(it->sname);
|
||||
#endif
|
||||
|
||||
switch(it->itype)
|
||||
{
|
||||
switch (it->itype) {
|
||||
|
||||
case ASN1_ITYPE_EXTERN:
|
||||
ef = it->funcs;
|
||||
if (ef && ef->asn1_ex_new)
|
||||
{
|
||||
if (!ef->asn1_ex_new(pval, it))
|
||||
goto memerr;
|
||||
}
|
||||
break;
|
||||
case ASN1_ITYPE_EXTERN:
|
||||
ef = it->funcs;
|
||||
if (ef && ef->asn1_ex_new) {
|
||||
if (!ef->asn1_ex_new(pval, it))
|
||||
goto memerr;
|
||||
}
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_COMPAT:
|
||||
cf = it->funcs;
|
||||
if (cf && cf->asn1_new) {
|
||||
*pval = cf->asn1_new();
|
||||
if (!*pval)
|
||||
goto memerr;
|
||||
}
|
||||
break;
|
||||
case ASN1_ITYPE_COMPAT:
|
||||
cf = it->funcs;
|
||||
if (cf && cf->asn1_new) {
|
||||
*pval = cf->asn1_new();
|
||||
if (!*pval)
|
||||
goto memerr;
|
||||
}
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_PRIMITIVE:
|
||||
if (it->templates)
|
||||
{
|
||||
if (!ASN1_template_new(pval, it->templates))
|
||||
goto memerr;
|
||||
}
|
||||
else if (!ASN1_primitive_new(pval, it))
|
||||
goto memerr;
|
||||
break;
|
||||
case ASN1_ITYPE_PRIMITIVE:
|
||||
if (it->templates) {
|
||||
if (!ASN1_template_new(pval, it->templates))
|
||||
goto memerr;
|
||||
} else if (!ASN1_primitive_new(pval, it))
|
||||
goto memerr;
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_MSTRING:
|
||||
if (!ASN1_primitive_new(pval, it))
|
||||
goto memerr;
|
||||
break;
|
||||
case ASN1_ITYPE_MSTRING:
|
||||
if (!ASN1_primitive_new(pval, it))
|
||||
goto memerr;
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_CHOICE:
|
||||
if (asn1_cb)
|
||||
{
|
||||
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
|
||||
if (!i)
|
||||
goto auxerr;
|
||||
if (i==2)
|
||||
{
|
||||
case ASN1_ITYPE_CHOICE:
|
||||
if (asn1_cb) {
|
||||
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
|
||||
if (!i)
|
||||
goto auxerr;
|
||||
if (i == 2) {
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
if (it->sname)
|
||||
CRYPTO_pop_info();
|
||||
if (it->sname)
|
||||
CRYPTO_pop_info();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!combine)
|
||||
{
|
||||
*pval = OPENSSL_malloc(it->size);
|
||||
if (!*pval)
|
||||
goto memerr;
|
||||
memset(*pval, 0, it->size);
|
||||
}
|
||||
asn1_set_choice_selector(pval, -1, it);
|
||||
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
|
||||
goto auxerr;
|
||||
break;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!combine) {
|
||||
*pval = OPENSSL_malloc(it->size);
|
||||
if (!*pval)
|
||||
goto memerr;
|
||||
memset(*pval, 0, it->size);
|
||||
}
|
||||
asn1_set_choice_selector(pval, -1, it);
|
||||
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
|
||||
goto auxerr;
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_NDEF_SEQUENCE:
|
||||
case ASN1_ITYPE_SEQUENCE:
|
||||
if (asn1_cb)
|
||||
{
|
||||
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
|
||||
if (!i)
|
||||
goto auxerr;
|
||||
if (i==2)
|
||||
{
|
||||
case ASN1_ITYPE_NDEF_SEQUENCE:
|
||||
case ASN1_ITYPE_SEQUENCE:
|
||||
if (asn1_cb) {
|
||||
i = asn1_cb(ASN1_OP_NEW_PRE, pval, it, NULL);
|
||||
if (!i)
|
||||
goto auxerr;
|
||||
if (i == 2) {
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
if (it->sname)
|
||||
CRYPTO_pop_info();
|
||||
if (it->sname)
|
||||
CRYPTO_pop_info();
|
||||
#endif
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!combine)
|
||||
{
|
||||
*pval = OPENSSL_malloc(it->size);
|
||||
if (!*pval)
|
||||
goto memerr;
|
||||
memset(*pval, 0, it->size);
|
||||
asn1_do_lock(pval, 0, it);
|
||||
asn1_enc_init(pval, it);
|
||||
}
|
||||
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++)
|
||||
{
|
||||
pseqval = asn1_get_field_ptr(pval, tt);
|
||||
if (!ASN1_template_new(pseqval, tt))
|
||||
goto memerr;
|
||||
}
|
||||
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
|
||||
goto auxerr;
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
if (!combine) {
|
||||
*pval = OPENSSL_malloc(it->size);
|
||||
if (!*pval)
|
||||
goto memerr;
|
||||
memset(*pval, 0, it->size);
|
||||
asn1_do_lock(pval, 0, it);
|
||||
asn1_enc_init(pval, it);
|
||||
}
|
||||
for (i = 0, tt = it->templates; i < it->tcount; tt++, i++) {
|
||||
pseqval = asn1_get_field_ptr(pval, tt);
|
||||
if (!ASN1_template_new(pseqval, tt))
|
||||
goto memerr;
|
||||
}
|
||||
if (asn1_cb && !asn1_cb(ASN1_OP_NEW_POST, pval, it, NULL))
|
||||
goto auxerr;
|
||||
break;
|
||||
}
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
if (it->sname) CRYPTO_pop_info();
|
||||
if (it->sname)
|
||||
CRYPTO_pop_info();
|
||||
#endif
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
memerr:
|
||||
ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);
|
||||
memerr:
|
||||
ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ERR_R_MALLOC_FAILURE);
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
if (it->sname) CRYPTO_pop_info();
|
||||
if (it->sname)
|
||||
CRYPTO_pop_info();
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
auxerr:
|
||||
ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);
|
||||
ASN1_item_ex_free(pval, it);
|
||||
auxerr:
|
||||
ASN1err(ASN1_F_ASN1_ITEM_EX_COMBINE_NEW, ASN1_R_AUX_ERROR);
|
||||
ASN1_item_ex_free(pval, it);
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
if (it->sname) CRYPTO_pop_info();
|
||||
if (it->sname)
|
||||
CRYPTO_pop_info();
|
||||
#endif
|
||||
return 0;
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static void asn1_item_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
const ASN1_EXTERN_FUNCS *ef;
|
||||
{
|
||||
const ASN1_EXTERN_FUNCS *ef;
|
||||
|
||||
switch(it->itype)
|
||||
{
|
||||
switch (it->itype) {
|
||||
|
||||
case ASN1_ITYPE_EXTERN:
|
||||
ef = it->funcs;
|
||||
if (ef && ef->asn1_ex_clear)
|
||||
ef->asn1_ex_clear(pval, it);
|
||||
else *pval = NULL;
|
||||
break;
|
||||
case ASN1_ITYPE_EXTERN:
|
||||
ef = it->funcs;
|
||||
if (ef && ef->asn1_ex_clear)
|
||||
ef->asn1_ex_clear(pval, it);
|
||||
else
|
||||
*pval = NULL;
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_PRIMITIVE:
|
||||
if (it->templates)
|
||||
asn1_template_clear(pval, it->templates);
|
||||
else
|
||||
asn1_primitive_clear(pval, it);
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_PRIMITIVE:
|
||||
if (it->templates)
|
||||
asn1_template_clear(pval, it->templates);
|
||||
else
|
||||
asn1_primitive_clear(pval, it);
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_MSTRING:
|
||||
asn1_primitive_clear(pval, it);
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_COMPAT:
|
||||
case ASN1_ITYPE_CHOICE:
|
||||
case ASN1_ITYPE_SEQUENCE:
|
||||
case ASN1_ITYPE_NDEF_SEQUENCE:
|
||||
*pval = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
case ASN1_ITYPE_MSTRING:
|
||||
asn1_primitive_clear(pval, it);
|
||||
break;
|
||||
|
||||
case ASN1_ITYPE_COMPAT:
|
||||
case ASN1_ITYPE_CHOICE:
|
||||
case ASN1_ITYPE_SEQUENCE:
|
||||
case ASN1_ITYPE_NDEF_SEQUENCE:
|
||||
*pval = NULL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
int ASN1_template_new(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
|
||||
{
|
||||
const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
|
||||
int ret;
|
||||
if (tt->flags & ASN1_TFLG_OPTIONAL)
|
||||
{
|
||||
asn1_template_clear(pval, tt);
|
||||
return 1;
|
||||
}
|
||||
/* If ANY DEFINED BY nothing to do */
|
||||
{
|
||||
const ASN1_ITEM *it = ASN1_ITEM_ptr(tt->item);
|
||||
int ret;
|
||||
if (tt->flags & ASN1_TFLG_OPTIONAL) {
|
||||
asn1_template_clear(pval, tt);
|
||||
return 1;
|
||||
}
|
||||
/* If ANY DEFINED BY nothing to do */
|
||||
|
||||
if (tt->flags & ASN1_TFLG_ADB_MASK)
|
||||
{
|
||||
*pval = NULL;
|
||||
return 1;
|
||||
}
|
||||
if (tt->flags & ASN1_TFLG_ADB_MASK) {
|
||||
*pval = NULL;
|
||||
return 1;
|
||||
}
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
if (tt->field_name)
|
||||
CRYPTO_push_info(tt->field_name);
|
||||
if (tt->field_name)
|
||||
CRYPTO_push_info(tt->field_name);
|
||||
#endif
|
||||
/* If SET OF or SEQUENCE OF, its a STACK */
|
||||
if (tt->flags & ASN1_TFLG_SK_MASK)
|
||||
{
|
||||
STACK_OF(ASN1_VALUE) *skval;
|
||||
skval = sk_ASN1_VALUE_new_null();
|
||||
if (!skval)
|
||||
{
|
||||
ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
*pval = (ASN1_VALUE *)skval;
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
/* Otherwise pass it back to the item routine */
|
||||
ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
|
||||
done:
|
||||
/* If SET OF or SEQUENCE OF, its a STACK */
|
||||
if (tt->flags & ASN1_TFLG_SK_MASK) {
|
||||
STACK_OF(ASN1_VALUE) *skval;
|
||||
skval = sk_ASN1_VALUE_new_null();
|
||||
if (!skval) {
|
||||
ASN1err(ASN1_F_ASN1_TEMPLATE_NEW, ERR_R_MALLOC_FAILURE);
|
||||
ret = 0;
|
||||
goto done;
|
||||
}
|
||||
*pval = (ASN1_VALUE *)skval;
|
||||
ret = 1;
|
||||
goto done;
|
||||
}
|
||||
/* Otherwise pass it back to the item routine */
|
||||
ret = asn1_item_ex_combine_new(pval, it, tt->flags & ASN1_TFLG_COMBINE);
|
||||
done:
|
||||
#ifdef CRYPTO_MDEBUG
|
||||
if (it->sname)
|
||||
CRYPTO_pop_info();
|
||||
if (it->sname)
|
||||
CRYPTO_pop_info();
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void asn1_template_clear(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
|
||||
{
|
||||
/* If ADB or STACK just NULL the field */
|
||||
if (tt->flags & (ASN1_TFLG_ADB_MASK|ASN1_TFLG_SK_MASK))
|
||||
*pval = NULL;
|
||||
else
|
||||
asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
|
||||
}
|
||||
{
|
||||
/* If ADB or STACK just NULL the field */
|
||||
if (tt->flags & (ASN1_TFLG_ADB_MASK | ASN1_TFLG_SK_MASK))
|
||||
*pval = NULL;
|
||||
else
|
||||
asn1_item_clear(pval, ASN1_ITEM_ptr(tt->item));
|
||||
}
|
||||
|
||||
|
||||
/* NB: could probably combine most of the real XXX_new() behaviour and junk
|
||||
/*
|
||||
* NB: could probably combine most of the real XXX_new() behaviour and junk
|
||||
* all the old functions.
|
||||
*/
|
||||
|
||||
int ASN1_primitive_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
ASN1_TYPE *typ;
|
||||
ASN1_STRING *str;
|
||||
int utype;
|
||||
{
|
||||
ASN1_TYPE *typ;
|
||||
ASN1_STRING *str;
|
||||
int utype;
|
||||
|
||||
if (it && it->funcs)
|
||||
{
|
||||
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
|
||||
if (pf->prim_new)
|
||||
return pf->prim_new(pval, it);
|
||||
}
|
||||
if (!it)
|
||||
return 0;
|
||||
|
||||
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
|
||||
utype = -1;
|
||||
else
|
||||
utype = it->utype;
|
||||
switch(utype)
|
||||
{
|
||||
case V_ASN1_OBJECT:
|
||||
*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
|
||||
return 1;
|
||||
if (it->funcs) {
|
||||
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
|
||||
if (pf->prim_new)
|
||||
return pf->prim_new(pval, it);
|
||||
}
|
||||
|
||||
case V_ASN1_BOOLEAN:
|
||||
*(ASN1_BOOLEAN *)pval = it->size;
|
||||
return 1;
|
||||
if (it->itype == ASN1_ITYPE_MSTRING)
|
||||
utype = -1;
|
||||
else
|
||||
utype = it->utype;
|
||||
switch (utype) {
|
||||
case V_ASN1_OBJECT:
|
||||
*pval = (ASN1_VALUE *)OBJ_nid2obj(NID_undef);
|
||||
return 1;
|
||||
|
||||
case V_ASN1_NULL:
|
||||
*pval = (ASN1_VALUE *)1;
|
||||
return 1;
|
||||
case V_ASN1_BOOLEAN:
|
||||
*(ASN1_BOOLEAN *)pval = it->size;
|
||||
return 1;
|
||||
|
||||
case V_ASN1_ANY:
|
||||
typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
|
||||
if (!typ)
|
||||
return 0;
|
||||
typ->value.ptr = NULL;
|
||||
typ->type = -1;
|
||||
*pval = (ASN1_VALUE *)typ;
|
||||
break;
|
||||
case V_ASN1_NULL:
|
||||
*pval = (ASN1_VALUE *)1;
|
||||
return 1;
|
||||
|
||||
default:
|
||||
str = ASN1_STRING_type_new(utype);
|
||||
if (it->itype == ASN1_ITYPE_MSTRING && str)
|
||||
str->flags |= ASN1_STRING_FLAG_MSTRING;
|
||||
*pval = (ASN1_VALUE *)str;
|
||||
break;
|
||||
}
|
||||
if (*pval)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
case V_ASN1_ANY:
|
||||
typ = OPENSSL_malloc(sizeof(ASN1_TYPE));
|
||||
if (!typ)
|
||||
return 0;
|
||||
typ->value.ptr = NULL;
|
||||
typ->type = -1;
|
||||
*pval = (ASN1_VALUE *)typ;
|
||||
break;
|
||||
|
||||
default:
|
||||
str = ASN1_STRING_type_new(utype);
|
||||
if (it->itype == ASN1_ITYPE_MSTRING && str)
|
||||
str->flags |= ASN1_STRING_FLAG_MSTRING;
|
||||
*pval = (ASN1_VALUE *)str;
|
||||
break;
|
||||
}
|
||||
if (*pval)
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void asn1_primitive_clear(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
int utype;
|
||||
if (it && it->funcs)
|
||||
{
|
||||
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
|
||||
if (pf->prim_clear)
|
||||
pf->prim_clear(pval, it);
|
||||
else
|
||||
*pval = NULL;
|
||||
return;
|
||||
}
|
||||
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
|
||||
utype = -1;
|
||||
else
|
||||
utype = it->utype;
|
||||
if (utype == V_ASN1_BOOLEAN)
|
||||
*(ASN1_BOOLEAN *)pval = it->size;
|
||||
else *pval = NULL;
|
||||
}
|
||||
{
|
||||
int utype;
|
||||
if (it && it->funcs) {
|
||||
const ASN1_PRIMITIVE_FUNCS *pf = it->funcs;
|
||||
if (pf->prim_clear)
|
||||
pf->prim_clear(pval, it);
|
||||
else
|
||||
*pval = NULL;
|
||||
return;
|
||||
}
|
||||
if (!it || (it->itype == ASN1_ITYPE_MSTRING))
|
||||
utype = -1;
|
||||
else
|
||||
utype = it->utype;
|
||||
if (utype == V_ASN1_BOOLEAN)
|
||||
*(ASN1_BOOLEAN *)pval = it->size;
|
||||
else
|
||||
*pval = NULL;
|
||||
}
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@ -1,6 +1,7 @@
|
||||
/* tasn_typ.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2000.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2000.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -136,12 +137,12 @@ IMPLEMENT_ASN1_TYPE_ex(ASN1_FBOOLEAN, ASN1_BOOLEAN, 0)
|
||||
|
||||
IMPLEMENT_ASN1_TYPE_ex(ASN1_OCTET_STRING_NDEF, ASN1_OCTET_STRING, ASN1_TFLG_NDEF)
|
||||
|
||||
ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY)
|
||||
ASN1_ITEM_TEMPLATE(ASN1_SEQUENCE_ANY) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, ASN1_SEQUENCE_ANY, ASN1_ANY)
|
||||
ASN1_ITEM_TEMPLATE_END(ASN1_SEQUENCE_ANY)
|
||||
|
||||
ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
|
||||
ASN1_ITEM_TEMPLATE(ASN1_SET_ANY) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, ASN1_SET_ANY, ASN1_ANY)
|
||||
ASN1_ITEM_TEMPLATE_END(ASN1_SET_ANY)
|
||||
|
||||
IMPLEMENT_ASN1_ENCODE_FUNCTIONS_const_fname(ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY, ASN1_SEQUENCE_ANY)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* tasn_utl.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2000.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2000.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2000-2004 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -56,7 +57,6 @@
|
||||
*
|
||||
*/
|
||||
|
||||
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <openssl/asn1.h>
|
||||
@ -69,211 +69,207 @@
|
||||
/* Add 'offset' to 'addr' */
|
||||
#define offset2ptr(addr, offset) (void *)(((char *) addr) + offset)
|
||||
|
||||
/* Given an ASN1_ITEM CHOICE type return
|
||||
* the selector value
|
||||
/*
|
||||
* Given an ASN1_ITEM CHOICE type return the selector value
|
||||
*/
|
||||
|
||||
int asn1_get_choice_selector(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
int *sel = offset2ptr(*pval, it->utype);
|
||||
return *sel;
|
||||
}
|
||||
{
|
||||
int *sel = offset2ptr(*pval, it->utype);
|
||||
return *sel;
|
||||
}
|
||||
|
||||
/* Given an ASN1_ITEM CHOICE type set
|
||||
* the selector value, return old value.
|
||||
/*
|
||||
* Given an ASN1_ITEM CHOICE type set the selector value, return old value.
|
||||
*/
|
||||
|
||||
int asn1_set_choice_selector(ASN1_VALUE **pval, int value, const ASN1_ITEM *it)
|
||||
{
|
||||
int *sel, ret;
|
||||
sel = offset2ptr(*pval, it->utype);
|
||||
ret = *sel;
|
||||
*sel = value;
|
||||
return ret;
|
||||
}
|
||||
int asn1_set_choice_selector(ASN1_VALUE **pval, int value,
|
||||
const ASN1_ITEM *it)
|
||||
{
|
||||
int *sel, ret;
|
||||
sel = offset2ptr(*pval, it->utype);
|
||||
ret = *sel;
|
||||
*sel = value;
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Do reference counting. The value 'op' decides what to do.
|
||||
* if it is +1 then the count is incremented. If op is 0 count is
|
||||
* set to 1. If op is -1 count is decremented and the return value
|
||||
* is the current refrence count or 0 if no reference count exists.
|
||||
/*
|
||||
* Do reference counting. The value 'op' decides what to do. if it is +1
|
||||
* then the count is incremented. If op is 0 count is set to 1. If op is -1
|
||||
* count is decremented and the return value is the current refrence count or
|
||||
* 0 if no reference count exists.
|
||||
*/
|
||||
|
||||
int asn1_do_lock(ASN1_VALUE **pval, int op, const ASN1_ITEM *it)
|
||||
{
|
||||
const ASN1_AUX *aux;
|
||||
int *lck, ret;
|
||||
if ((it->itype != ASN1_ITYPE_SEQUENCE)
|
||||
&& (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
|
||||
return 0;
|
||||
aux = it->funcs;
|
||||
if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
|
||||
return 0;
|
||||
lck = offset2ptr(*pval, aux->ref_offset);
|
||||
if (op == 0)
|
||||
{
|
||||
*lck = 1;
|
||||
return 1;
|
||||
}
|
||||
ret = CRYPTO_add(lck, op, aux->ref_lock);
|
||||
{
|
||||
const ASN1_AUX *aux;
|
||||
int *lck, ret;
|
||||
if ((it->itype != ASN1_ITYPE_SEQUENCE)
|
||||
&& (it->itype != ASN1_ITYPE_NDEF_SEQUENCE))
|
||||
return 0;
|
||||
aux = it->funcs;
|
||||
if (!aux || !(aux->flags & ASN1_AFLG_REFCOUNT))
|
||||
return 0;
|
||||
lck = offset2ptr(*pval, aux->ref_offset);
|
||||
if (op == 0) {
|
||||
*lck = 1;
|
||||
return 1;
|
||||
}
|
||||
ret = CRYPTO_add(lck, op, aux->ref_lock);
|
||||
#ifdef REF_PRINT
|
||||
fprintf(stderr, "%s: Reference Count: %d\n", it->sname, *lck);
|
||||
fprintf(stderr, "%s: Reference Count: %d\n", it->sname, *lck);
|
||||
#endif
|
||||
#ifdef REF_CHECK
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "%s, bad reference count\n", it->sname);
|
||||
if (ret < 0)
|
||||
fprintf(stderr, "%s, bad reference count\n", it->sname);
|
||||
#endif
|
||||
return ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static ASN1_ENCODING *asn1_get_enc_ptr(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
const ASN1_AUX *aux;
|
||||
if (!pval || !*pval)
|
||||
return NULL;
|
||||
aux = it->funcs;
|
||||
if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
|
||||
return NULL;
|
||||
return offset2ptr(*pval, aux->enc_offset);
|
||||
}
|
||||
{
|
||||
const ASN1_AUX *aux;
|
||||
if (!pval || !*pval)
|
||||
return NULL;
|
||||
aux = it->funcs;
|
||||
if (!aux || !(aux->flags & ASN1_AFLG_ENCODING))
|
||||
return NULL;
|
||||
return offset2ptr(*pval, aux->enc_offset);
|
||||
}
|
||||
|
||||
void asn1_enc_init(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
ASN1_ENCODING *enc;
|
||||
enc = asn1_get_enc_ptr(pval, it);
|
||||
if (enc)
|
||||
{
|
||||
enc->enc = NULL;
|
||||
enc->len = 0;
|
||||
enc->modified = 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
ASN1_ENCODING *enc;
|
||||
enc = asn1_get_enc_ptr(pval, it);
|
||||
if (enc) {
|
||||
enc->enc = NULL;
|
||||
enc->len = 0;
|
||||
enc->modified = 1;
|
||||
}
|
||||
}
|
||||
|
||||
void asn1_enc_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
ASN1_ENCODING *enc;
|
||||
enc = asn1_get_enc_ptr(pval, it);
|
||||
if (enc)
|
||||
{
|
||||
if (enc->enc)
|
||||
OPENSSL_free(enc->enc);
|
||||
enc->enc = NULL;
|
||||
enc->len = 0;
|
||||
enc->modified = 1;
|
||||
}
|
||||
}
|
||||
{
|
||||
ASN1_ENCODING *enc;
|
||||
enc = asn1_get_enc_ptr(pval, it);
|
||||
if (enc) {
|
||||
if (enc->enc)
|
||||
OPENSSL_free(enc->enc);
|
||||
enc->enc = NULL;
|
||||
enc->len = 0;
|
||||
enc->modified = 1;
|
||||
}
|
||||
}
|
||||
|
||||
int asn1_enc_save(ASN1_VALUE **pval, const unsigned char *in, int inlen,
|
||||
const ASN1_ITEM *it)
|
||||
{
|
||||
ASN1_ENCODING *enc;
|
||||
enc = asn1_get_enc_ptr(pval, it);
|
||||
if (!enc)
|
||||
return 1;
|
||||
const ASN1_ITEM *it)
|
||||
{
|
||||
ASN1_ENCODING *enc;
|
||||
enc = asn1_get_enc_ptr(pval, it);
|
||||
if (!enc)
|
||||
return 1;
|
||||
|
||||
if (enc->enc)
|
||||
OPENSSL_free(enc->enc);
|
||||
enc->enc = OPENSSL_malloc(inlen);
|
||||
if (!enc->enc)
|
||||
return 0;
|
||||
memcpy(enc->enc, in, inlen);
|
||||
enc->len = inlen;
|
||||
enc->modified = 0;
|
||||
if (enc->enc)
|
||||
OPENSSL_free(enc->enc);
|
||||
enc->enc = OPENSSL_malloc(inlen);
|
||||
if (!enc->enc)
|
||||
return 0;
|
||||
memcpy(enc->enc, in, inlen);
|
||||
enc->len = inlen;
|
||||
enc->modified = 0;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
int asn1_enc_restore(int *len, unsigned char **out, ASN1_VALUE **pval,
|
||||
const ASN1_ITEM *it)
|
||||
{
|
||||
ASN1_ENCODING *enc;
|
||||
enc = asn1_get_enc_ptr(pval, it);
|
||||
if (!enc || enc->modified)
|
||||
return 0;
|
||||
if (out)
|
||||
{
|
||||
memcpy(*out, enc->enc, enc->len);
|
||||
*out += enc->len;
|
||||
}
|
||||
if (len)
|
||||
*len = enc->len;
|
||||
return 1;
|
||||
}
|
||||
const ASN1_ITEM *it)
|
||||
{
|
||||
ASN1_ENCODING *enc;
|
||||
enc = asn1_get_enc_ptr(pval, it);
|
||||
if (!enc || enc->modified)
|
||||
return 0;
|
||||
if (out) {
|
||||
memcpy(*out, enc->enc, enc->len);
|
||||
*out += enc->len;
|
||||
}
|
||||
if (len)
|
||||
*len = enc->len;
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Given an ASN1_TEMPLATE get a pointer to a field */
|
||||
ASN1_VALUE ** asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
|
||||
{
|
||||
ASN1_VALUE **pvaltmp;
|
||||
if (tt->flags & ASN1_TFLG_COMBINE)
|
||||
return pval;
|
||||
pvaltmp = offset2ptr(*pval, tt->offset);
|
||||
/* NOTE for BOOLEAN types the field is just a plain
|
||||
* int so we can't return int **, so settle for
|
||||
* (int *).
|
||||
*/
|
||||
return pvaltmp;
|
||||
}
|
||||
ASN1_VALUE **asn1_get_field_ptr(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt)
|
||||
{
|
||||
ASN1_VALUE **pvaltmp;
|
||||
if (tt->flags & ASN1_TFLG_COMBINE)
|
||||
return pval;
|
||||
pvaltmp = offset2ptr(*pval, tt->offset);
|
||||
/*
|
||||
* NOTE for BOOLEAN types the field is just a plain int so we can't
|
||||
* return int **, so settle for (int *).
|
||||
*/
|
||||
return pvaltmp;
|
||||
}
|
||||
|
||||
/* Handle ANY DEFINED BY template, find the selector, look up
|
||||
* the relevant ASN1_TEMPLATE in the table and return it.
|
||||
/*
|
||||
* Handle ANY DEFINED BY template, find the selector, look up the relevant
|
||||
* ASN1_TEMPLATE in the table and return it.
|
||||
*/
|
||||
|
||||
const ASN1_TEMPLATE *asn1_do_adb(ASN1_VALUE **pval, const ASN1_TEMPLATE *tt,
|
||||
int nullerr)
|
||||
{
|
||||
const ASN1_ADB *adb;
|
||||
const ASN1_ADB_TABLE *atbl;
|
||||
long selector;
|
||||
ASN1_VALUE **sfld;
|
||||
int i;
|
||||
if (!(tt->flags & ASN1_TFLG_ADB_MASK))
|
||||
return tt;
|
||||
int nullerr)
|
||||
{
|
||||
const ASN1_ADB *adb;
|
||||
const ASN1_ADB_TABLE *atbl;
|
||||
long selector;
|
||||
ASN1_VALUE **sfld;
|
||||
int i;
|
||||
if (!(tt->flags & ASN1_TFLG_ADB_MASK))
|
||||
return tt;
|
||||
|
||||
/* Else ANY DEFINED BY ... get the table */
|
||||
adb = ASN1_ADB_ptr(tt->item);
|
||||
/* Else ANY DEFINED BY ... get the table */
|
||||
adb = ASN1_ADB_ptr(tt->item);
|
||||
|
||||
/* Get the selector field */
|
||||
sfld = offset2ptr(*pval, adb->offset);
|
||||
/* Get the selector field */
|
||||
sfld = offset2ptr(*pval, adb->offset);
|
||||
|
||||
/* Check if NULL */
|
||||
if (!sfld)
|
||||
{
|
||||
if (!adb->null_tt)
|
||||
goto err;
|
||||
return adb->null_tt;
|
||||
}
|
||||
/* Check if NULL */
|
||||
if (!sfld) {
|
||||
if (!adb->null_tt)
|
||||
goto err;
|
||||
return adb->null_tt;
|
||||
}
|
||||
|
||||
/* Convert type to a long:
|
||||
* NB: don't check for NID_undef here because it
|
||||
* might be a legitimate value in the table
|
||||
*/
|
||||
if (tt->flags & ASN1_TFLG_ADB_OID)
|
||||
selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
|
||||
else
|
||||
selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
|
||||
/*
|
||||
* Convert type to a long: NB: don't check for NID_undef here because it
|
||||
* might be a legitimate value in the table
|
||||
*/
|
||||
if (tt->flags & ASN1_TFLG_ADB_OID)
|
||||
selector = OBJ_obj2nid((ASN1_OBJECT *)*sfld);
|
||||
else
|
||||
selector = ASN1_INTEGER_get((ASN1_INTEGER *)*sfld);
|
||||
|
||||
/* Try to find matching entry in table
|
||||
* Maybe should check application types first to
|
||||
* allow application override? Might also be useful
|
||||
* to have a flag which indicates table is sorted and
|
||||
* we can do a binary search. For now stick to a
|
||||
* linear search.
|
||||
*/
|
||||
/*
|
||||
* Try to find matching entry in table Maybe should check application
|
||||
* types first to allow application override? Might also be useful to
|
||||
* have a flag which indicates table is sorted and we can do a binary
|
||||
* search. For now stick to a linear search.
|
||||
*/
|
||||
|
||||
for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
|
||||
if (atbl->value == selector)
|
||||
return &atbl->tt;
|
||||
for (atbl = adb->tbl, i = 0; i < adb->tblcount; i++, atbl++)
|
||||
if (atbl->value == selector)
|
||||
return &atbl->tt;
|
||||
|
||||
/* FIXME: need to search application table too */
|
||||
/* FIXME: need to search application table too */
|
||||
|
||||
/* No match, return default type */
|
||||
if (!adb->default_tt)
|
||||
goto err;
|
||||
return adb->default_tt;
|
||||
|
||||
err:
|
||||
/* FIXME: should log the value or OID of unsupported type */
|
||||
if (nullerr)
|
||||
ASN1err(ASN1_F_ASN1_DO_ADB,
|
||||
ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
|
||||
return NULL;
|
||||
}
|
||||
/* No match, return default type */
|
||||
if (!adb->default_tt)
|
||||
goto err;
|
||||
return adb->default_tt;
|
||||
|
||||
err:
|
||||
/* FIXME: should log the value or OID of unsupported type */
|
||||
if (nullerr)
|
||||
ASN1err(ASN1_F_ASN1_DO_ADB, ASN1_R_UNSUPPORTED_ANY_DEFINED_BY_TYPE);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* x_algor.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2000.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2000.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -62,12 +63,12 @@
|
||||
#include <openssl/asn1t.h>
|
||||
|
||||
ASN1_SEQUENCE(X509_ALGOR) = {
|
||||
ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
|
||||
ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
|
||||
ASN1_SIMPLE(X509_ALGOR, algorithm, ASN1_OBJECT),
|
||||
ASN1_OPT(X509_ALGOR, parameter, ASN1_ANY)
|
||||
} ASN1_SEQUENCE_END(X509_ALGOR)
|
||||
|
||||
ASN1_ITEM_TEMPLATE(X509_ALGORS) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
|
||||
ASN1_ITEM_TEMPLATE(X509_ALGORS) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, algorithms, X509_ALGOR)
|
||||
ASN1_ITEM_TEMPLATE_END(X509_ALGORS)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_ALGOR)
|
||||
@ -78,67 +79,70 @@ IMPLEMENT_STACK_OF(X509_ALGOR)
|
||||
IMPLEMENT_ASN1_SET_OF(X509_ALGOR)
|
||||
|
||||
int X509_ALGOR_set0(X509_ALGOR *alg, ASN1_OBJECT *aobj, int ptype, void *pval)
|
||||
{
|
||||
if (!alg)
|
||||
return 0;
|
||||
if (ptype != V_ASN1_UNDEF)
|
||||
{
|
||||
if (alg->parameter == NULL)
|
||||
alg->parameter = ASN1_TYPE_new();
|
||||
if (alg->parameter == NULL)
|
||||
return 0;
|
||||
}
|
||||
if (alg)
|
||||
{
|
||||
if (alg->algorithm)
|
||||
ASN1_OBJECT_free(alg->algorithm);
|
||||
alg->algorithm = aobj;
|
||||
}
|
||||
if (ptype == 0)
|
||||
return 1;
|
||||
if (ptype == V_ASN1_UNDEF)
|
||||
{
|
||||
if (alg->parameter)
|
||||
{
|
||||
ASN1_TYPE_free(alg->parameter);
|
||||
alg->parameter = NULL;
|
||||
}
|
||||
}
|
||||
else
|
||||
ASN1_TYPE_set(alg->parameter, ptype, pval);
|
||||
return 1;
|
||||
}
|
||||
{
|
||||
if (!alg)
|
||||
return 0;
|
||||
if (ptype != V_ASN1_UNDEF) {
|
||||
if (alg->parameter == NULL)
|
||||
alg->parameter = ASN1_TYPE_new();
|
||||
if (alg->parameter == NULL)
|
||||
return 0;
|
||||
}
|
||||
if (alg) {
|
||||
if (alg->algorithm)
|
||||
ASN1_OBJECT_free(alg->algorithm);
|
||||
alg->algorithm = aobj;
|
||||
}
|
||||
if (ptype == 0)
|
||||
return 1;
|
||||
if (ptype == V_ASN1_UNDEF) {
|
||||
if (alg->parameter) {
|
||||
ASN1_TYPE_free(alg->parameter);
|
||||
alg->parameter = NULL;
|
||||
}
|
||||
} else
|
||||
ASN1_TYPE_set(alg->parameter, ptype, pval);
|
||||
return 1;
|
||||
}
|
||||
|
||||
void X509_ALGOR_get0(ASN1_OBJECT **paobj, int *pptype, void **ppval,
|
||||
X509_ALGOR *algor)
|
||||
{
|
||||
if (paobj)
|
||||
*paobj = algor->algorithm;
|
||||
if (pptype)
|
||||
{
|
||||
if (algor->parameter == NULL)
|
||||
{
|
||||
*pptype = V_ASN1_UNDEF;
|
||||
return;
|
||||
}
|
||||
else
|
||||
*pptype = algor->parameter->type;
|
||||
if (ppval)
|
||||
*ppval = algor->parameter->value.ptr;
|
||||
}
|
||||
}
|
||||
X509_ALGOR *algor)
|
||||
{
|
||||
if (paobj)
|
||||
*paobj = algor->algorithm;
|
||||
if (pptype) {
|
||||
if (algor->parameter == NULL) {
|
||||
*pptype = V_ASN1_UNDEF;
|
||||
return;
|
||||
} else
|
||||
*pptype = algor->parameter->type;
|
||||
if (ppval)
|
||||
*ppval = algor->parameter->value.ptr;
|
||||
}
|
||||
}
|
||||
|
||||
/* Set up an X509_ALGOR DigestAlgorithmIdentifier from an EVP_MD */
|
||||
|
||||
void X509_ALGOR_set_md(X509_ALGOR *alg, const EVP_MD *md)
|
||||
{
|
||||
int param_type;
|
||||
{
|
||||
int param_type;
|
||||
|
||||
if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
|
||||
param_type = V_ASN1_UNDEF;
|
||||
else
|
||||
param_type = V_ASN1_NULL;
|
||||
if (md->flags & EVP_MD_FLAG_DIGALGID_ABSENT)
|
||||
param_type = V_ASN1_UNDEF;
|
||||
else
|
||||
param_type = V_ASN1_NULL;
|
||||
|
||||
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
|
||||
X509_ALGOR_set0(alg, OBJ_nid2obj(EVP_MD_type(md)), param_type, NULL);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
int X509_ALGOR_cmp(const X509_ALGOR *a, const X509_ALGOR *b)
|
||||
{
|
||||
int rv;
|
||||
rv = OBJ_cmp(a->algorithm, b->algorithm);
|
||||
if (rv)
|
||||
return rv;
|
||||
if (!a->parameter && !b->parameter)
|
||||
return 0;
|
||||
return ASN1_TYPE_cmp(a->parameter, b->parameter);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,18 +62,19 @@
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
/* X509_ATTRIBUTE: this has the following form:
|
||||
/*-
|
||||
* X509_ATTRIBUTE: this has the following form:
|
||||
*
|
||||
* typedef struct x509_attributes_st
|
||||
* {
|
||||
* ASN1_OBJECT *object;
|
||||
* int single;
|
||||
* union {
|
||||
* char *ptr;
|
||||
* STACK_OF(ASN1_TYPE) *set;
|
||||
* ASN1_TYPE *single;
|
||||
* } value;
|
||||
* } X509_ATTRIBUTE;
|
||||
* {
|
||||
* ASN1_OBJECT *object;
|
||||
* int single;
|
||||
* union {
|
||||
* char *ptr;
|
||||
* STACK_OF(ASN1_TYPE) *set;
|
||||
* ASN1_TYPE *single;
|
||||
* } value;
|
||||
* } X509_ATTRIBUTE;
|
||||
*
|
||||
* this needs some extra thought because the CHOICE type is
|
||||
* merged with the main structure and because the value can
|
||||
@ -83,36 +84,41 @@
|
||||
*/
|
||||
|
||||
ASN1_CHOICE(X509_ATTRIBUTE_SET) = {
|
||||
ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY),
|
||||
ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY)
|
||||
ASN1_SET_OF(X509_ATTRIBUTE, value.set, ASN1_ANY),
|
||||
ASN1_SIMPLE(X509_ATTRIBUTE, value.single, ASN1_ANY)
|
||||
} ASN1_CHOICE_END_selector(X509_ATTRIBUTE, X509_ATTRIBUTE_SET, single)
|
||||
|
||||
ASN1_SEQUENCE(X509_ATTRIBUTE) = {
|
||||
ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT),
|
||||
/* CHOICE type merged with parent */
|
||||
ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET)
|
||||
ASN1_SIMPLE(X509_ATTRIBUTE, object, ASN1_OBJECT),
|
||||
/* CHOICE type merged with parent */
|
||||
ASN1_EX_COMBINE(0, 0, X509_ATTRIBUTE_SET)
|
||||
} ASN1_SEQUENCE_END(X509_ATTRIBUTE)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_ATTRIBUTE)
|
||||
IMPLEMENT_ASN1_DUP_FUNCTION(X509_ATTRIBUTE)
|
||||
|
||||
X509_ATTRIBUTE *X509_ATTRIBUTE_create(int nid, int atrtype, void *value)
|
||||
{
|
||||
X509_ATTRIBUTE *ret=NULL;
|
||||
ASN1_TYPE *val=NULL;
|
||||
{
|
||||
X509_ATTRIBUTE *ret = NULL;
|
||||
ASN1_TYPE *val = NULL;
|
||||
|
||||
if ((ret=X509_ATTRIBUTE_new()) == NULL)
|
||||
return(NULL);
|
||||
ret->object=OBJ_nid2obj(nid);
|
||||
ret->single=0;
|
||||
if ((ret->value.set=sk_ASN1_TYPE_new_null()) == NULL) goto err;
|
||||
if ((val=ASN1_TYPE_new()) == NULL) goto err;
|
||||
if (!sk_ASN1_TYPE_push(ret->value.set,val)) goto err;
|
||||
if ((ret = X509_ATTRIBUTE_new()) == NULL)
|
||||
return (NULL);
|
||||
ret->object = OBJ_nid2obj(nid);
|
||||
ret->single = 0;
|
||||
if ((ret->value.set = sk_ASN1_TYPE_new_null()) == NULL)
|
||||
goto err;
|
||||
if ((val = ASN1_TYPE_new()) == NULL)
|
||||
goto err;
|
||||
if (!sk_ASN1_TYPE_push(ret->value.set, val))
|
||||
goto err;
|
||||
|
||||
ASN1_TYPE_set(val,atrtype,value);
|
||||
return(ret);
|
||||
err:
|
||||
if (ret != NULL) X509_ATTRIBUTE_free(ret);
|
||||
if (val != NULL) ASN1_TYPE_free(val);
|
||||
return(NULL);
|
||||
}
|
||||
ASN1_TYPE_set(val, atrtype, value);
|
||||
return (ret);
|
||||
err:
|
||||
if (ret != NULL)
|
||||
X509_ATTRIBUTE_free(ret);
|
||||
if (val != NULL)
|
||||
ASN1_TYPE_free(val);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* x_bignum.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2000.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2000.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -61,79 +62,92 @@
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
/* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER as a
|
||||
* BIGNUM directly. Currently it ignores the sign which isn't a problem since all
|
||||
* BIGNUMs used are non negative and anything that looks negative is normally due
|
||||
* to an encoding error.
|
||||
/*
|
||||
* Custom primitive type for BIGNUM handling. This reads in an ASN1_INTEGER
|
||||
* as a BIGNUM directly. Currently it ignores the sign which isn't a problem
|
||||
* since all BIGNUMs used are non negative and anything that looks negative
|
||||
* is normally due to an encoding error.
|
||||
*/
|
||||
|
||||
#define BN_SENSITIVE 1
|
||||
#define BN_SENSITIVE 1
|
||||
|
||||
static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
|
||||
static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
|
||||
|
||||
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
|
||||
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
|
||||
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
|
||||
const ASN1_ITEM *it);
|
||||
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
|
||||
int utype, char *free_cont, const ASN1_ITEM *it);
|
||||
|
||||
static ASN1_PRIMITIVE_FUNCS bignum_pf = {
|
||||
NULL, 0,
|
||||
bn_new,
|
||||
bn_free,
|
||||
0,
|
||||
bn_c2i,
|
||||
bn_i2c
|
||||
NULL, 0,
|
||||
bn_new,
|
||||
bn_free,
|
||||
0,
|
||||
bn_c2i,
|
||||
bn_i2c
|
||||
};
|
||||
|
||||
ASN1_ITEM_start(BIGNUM)
|
||||
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
|
||||
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, 0, "BIGNUM"
|
||||
ASN1_ITEM_end(BIGNUM)
|
||||
|
||||
ASN1_ITEM_start(CBIGNUM)
|
||||
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
|
||||
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &bignum_pf, BN_SENSITIVE, "BIGNUM"
|
||||
ASN1_ITEM_end(CBIGNUM)
|
||||
|
||||
static int bn_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
*pval = (ASN1_VALUE *)BN_new();
|
||||
if(*pval) return 1;
|
||||
else return 0;
|
||||
*pval = (ASN1_VALUE *)BN_new();
|
||||
if (*pval)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void bn_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
if(!*pval) return;
|
||||
if(it->size & BN_SENSITIVE) BN_clear_free((BIGNUM *)*pval);
|
||||
else BN_free((BIGNUM *)*pval);
|
||||
*pval = NULL;
|
||||
if (!*pval)
|
||||
return;
|
||||
if (it->size & BN_SENSITIVE)
|
||||
BN_clear_free((BIGNUM *)*pval);
|
||||
else
|
||||
BN_free((BIGNUM *)*pval);
|
||||
*pval = NULL;
|
||||
}
|
||||
|
||||
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
|
||||
static int bn_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
|
||||
const ASN1_ITEM *it)
|
||||
{
|
||||
BIGNUM *bn;
|
||||
int pad;
|
||||
if(!*pval) return -1;
|
||||
bn = (BIGNUM *)*pval;
|
||||
/* If MSB set in an octet we need a padding byte */
|
||||
if(BN_num_bits(bn) & 0x7) pad = 0;
|
||||
else pad = 1;
|
||||
if(cont) {
|
||||
if(pad) *cont++ = 0;
|
||||
BN_bn2bin(bn, cont);
|
||||
}
|
||||
return pad + BN_num_bytes(bn);
|
||||
BIGNUM *bn;
|
||||
int pad;
|
||||
if (!*pval)
|
||||
return -1;
|
||||
bn = (BIGNUM *)*pval;
|
||||
/* If MSB set in an octet we need a padding byte */
|
||||
if (BN_num_bits(bn) & 0x7)
|
||||
pad = 0;
|
||||
else
|
||||
pad = 1;
|
||||
if (cont) {
|
||||
if (pad)
|
||||
*cont++ = 0;
|
||||
BN_bn2bin(bn, cont);
|
||||
}
|
||||
return pad + BN_num_bytes(bn);
|
||||
}
|
||||
|
||||
static int bn_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
|
||||
int utype, char *free_cont, const ASN1_ITEM *it)
|
||||
int utype, char *free_cont, const ASN1_ITEM *it)
|
||||
{
|
||||
BIGNUM *bn;
|
||||
if(!*pval) bn_new(pval, it);
|
||||
bn = (BIGNUM *)*pval;
|
||||
if(!BN_bin2bn(cont, len, bn)) {
|
||||
bn_free(pval, it);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
BIGNUM *bn;
|
||||
|
||||
if (*pval == NULL && !bn_new(pval, it))
|
||||
return 0;
|
||||
bn = (BIGNUM *)*pval;
|
||||
if (!BN_bin2bn(cont, len, bn)) {
|
||||
bn_free(pval, it);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -63,465 +63,453 @@
|
||||
#include <openssl/x509.h>
|
||||
#include <openssl/x509v3.h>
|
||||
|
||||
static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
|
||||
const X509_REVOKED * const *b);
|
||||
static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
|
||||
const X509_REVOKED *const *b);
|
||||
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp);
|
||||
|
||||
ASN1_SEQUENCE(X509_REVOKED) = {
|
||||
ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
|
||||
ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
|
||||
ASN1_SIMPLE(X509_REVOKED,serialNumber, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(X509_REVOKED,revocationDate, ASN1_TIME),
|
||||
ASN1_SEQUENCE_OF_OPT(X509_REVOKED,extensions, X509_EXTENSION)
|
||||
} ASN1_SEQUENCE_END(X509_REVOKED)
|
||||
|
||||
static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r);
|
||||
static int def_crl_lookup(X509_CRL *crl,
|
||||
X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer);
|
||||
X509_REVOKED **ret, ASN1_INTEGER *serial,
|
||||
X509_NAME *issuer);
|
||||
|
||||
static X509_CRL_METHOD int_crl_meth =
|
||||
{
|
||||
0,
|
||||
0,0,
|
||||
def_crl_lookup,
|
||||
def_crl_verify
|
||||
};
|
||||
static X509_CRL_METHOD int_crl_meth = {
|
||||
0,
|
||||
0, 0,
|
||||
def_crl_lookup,
|
||||
def_crl_verify
|
||||
};
|
||||
|
||||
static const X509_CRL_METHOD *default_crl_method = &int_crl_meth;
|
||||
|
||||
/* The X509_CRL_INFO structure needs a bit of customisation.
|
||||
* Since we cache the original encoding the signature wont be affected by
|
||||
* reordering of the revoked field.
|
||||
/*
|
||||
* The X509_CRL_INFO structure needs a bit of customisation. Since we cache
|
||||
* the original encoding the signature wont be affected by reordering of the
|
||||
* revoked field.
|
||||
*/
|
||||
static int crl_inf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
void *exarg)
|
||||
void *exarg)
|
||||
{
|
||||
X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
|
||||
X509_CRL_INFO *a = (X509_CRL_INFO *)*pval;
|
||||
|
||||
if(!a || !a->revoked) return 1;
|
||||
switch(operation) {
|
||||
/* Just set cmp function here. We don't sort because that
|
||||
* would affect the output of X509_CRL_print().
|
||||
*/
|
||||
case ASN1_OP_D2I_POST:
|
||||
(void)sk_X509_REVOKED_set_cmp_func(a->revoked,X509_REVOKED_cmp);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
if (!a || !a->revoked)
|
||||
return 1;
|
||||
switch (operation) {
|
||||
/*
|
||||
* Just set cmp function here. We don't sort because that would
|
||||
* affect the output of X509_CRL_print().
|
||||
*/
|
||||
case ASN1_OP_D2I_POST:
|
||||
(void)sk_X509_REVOKED_set_cmp_func(a->revoked, X509_REVOKED_cmp);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
||||
ASN1_SEQUENCE_enc(X509_CRL_INFO, enc, crl_inf_cb) = {
|
||||
ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
|
||||
ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
|
||||
ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
|
||||
ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
|
||||
ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
|
||||
ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
|
||||
ASN1_OPT(X509_CRL_INFO, version, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(X509_CRL_INFO, sig_alg, X509_ALGOR),
|
||||
ASN1_SIMPLE(X509_CRL_INFO, issuer, X509_NAME),
|
||||
ASN1_SIMPLE(X509_CRL_INFO, lastUpdate, ASN1_TIME),
|
||||
ASN1_OPT(X509_CRL_INFO, nextUpdate, ASN1_TIME),
|
||||
ASN1_SEQUENCE_OF_OPT(X509_CRL_INFO, revoked, X509_REVOKED),
|
||||
ASN1_EXP_SEQUENCE_OF_OPT(X509_CRL_INFO, extensions, X509_EXTENSION, 0)
|
||||
} ASN1_SEQUENCE_END_enc(X509_CRL_INFO, X509_CRL_INFO)
|
||||
|
||||
/* Set CRL entry issuer according to CRL certificate issuer extension.
|
||||
* Check for unhandled critical CRL entry extensions.
|
||||
/*
|
||||
* Set CRL entry issuer according to CRL certificate issuer extension. Check
|
||||
* for unhandled critical CRL entry extensions.
|
||||
*/
|
||||
|
||||
static int crl_set_issuers(X509_CRL *crl)
|
||||
{
|
||||
{
|
||||
|
||||
int i, j;
|
||||
GENERAL_NAMES *gens, *gtmp;
|
||||
STACK_OF(X509_REVOKED) *revoked;
|
||||
int i, j;
|
||||
GENERAL_NAMES *gens, *gtmp;
|
||||
STACK_OF(X509_REVOKED) *revoked;
|
||||
|
||||
revoked = X509_CRL_get_REVOKED(crl);
|
||||
revoked = X509_CRL_get_REVOKED(crl);
|
||||
|
||||
gens = NULL;
|
||||
for (i = 0; i < sk_X509_REVOKED_num(revoked); i++)
|
||||
{
|
||||
X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
|
||||
STACK_OF(X509_EXTENSION) *exts;
|
||||
ASN1_ENUMERATED *reason;
|
||||
X509_EXTENSION *ext;
|
||||
gtmp = X509_REVOKED_get_ext_d2i(rev,
|
||||
NID_certificate_issuer,
|
||||
&j, NULL);
|
||||
if (!gtmp && (j != -1))
|
||||
{
|
||||
crl->flags |= EXFLAG_INVALID;
|
||||
return 1;
|
||||
}
|
||||
gens = NULL;
|
||||
for (i = 0; i < sk_X509_REVOKED_num(revoked); i++) {
|
||||
X509_REVOKED *rev = sk_X509_REVOKED_value(revoked, i);
|
||||
STACK_OF(X509_EXTENSION) *exts;
|
||||
ASN1_ENUMERATED *reason;
|
||||
X509_EXTENSION *ext;
|
||||
gtmp = X509_REVOKED_get_ext_d2i(rev,
|
||||
NID_certificate_issuer, &j, NULL);
|
||||
if (!gtmp && (j != -1)) {
|
||||
crl->flags |= EXFLAG_INVALID;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (gtmp)
|
||||
{
|
||||
gens = gtmp;
|
||||
if (!crl->issuers)
|
||||
{
|
||||
crl->issuers = sk_GENERAL_NAMES_new_null();
|
||||
if (!crl->issuers)
|
||||
return 0;
|
||||
}
|
||||
if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
|
||||
return 0;
|
||||
}
|
||||
rev->issuer = gens;
|
||||
if (gtmp) {
|
||||
gens = gtmp;
|
||||
if (!crl->issuers) {
|
||||
crl->issuers = sk_GENERAL_NAMES_new_null();
|
||||
if (!crl->issuers)
|
||||
return 0;
|
||||
}
|
||||
if (!sk_GENERAL_NAMES_push(crl->issuers, gtmp))
|
||||
return 0;
|
||||
}
|
||||
rev->issuer = gens;
|
||||
|
||||
reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason,
|
||||
&j, NULL);
|
||||
if (!reason && (j != -1))
|
||||
{
|
||||
crl->flags |= EXFLAG_INVALID;
|
||||
return 1;
|
||||
}
|
||||
reason = X509_REVOKED_get_ext_d2i(rev, NID_crl_reason, &j, NULL);
|
||||
if (!reason && (j != -1)) {
|
||||
crl->flags |= EXFLAG_INVALID;
|
||||
return 1;
|
||||
}
|
||||
|
||||
if (reason)
|
||||
{
|
||||
rev->reason = ASN1_ENUMERATED_get(reason);
|
||||
ASN1_ENUMERATED_free(reason);
|
||||
}
|
||||
else
|
||||
rev->reason = CRL_REASON_NONE;
|
||||
if (reason) {
|
||||
rev->reason = ASN1_ENUMERATED_get(reason);
|
||||
ASN1_ENUMERATED_free(reason);
|
||||
} else
|
||||
rev->reason = CRL_REASON_NONE;
|
||||
|
||||
/* Check for critical CRL entry extensions */
|
||||
/* Check for critical CRL entry extensions */
|
||||
|
||||
exts = rev->extensions;
|
||||
exts = rev->extensions;
|
||||
|
||||
for (j = 0; j < sk_X509_EXTENSION_num(exts); j++)
|
||||
{
|
||||
ext = sk_X509_EXTENSION_value(exts, j);
|
||||
if (ext->critical > 0)
|
||||
{
|
||||
if (OBJ_obj2nid(ext->object) ==
|
||||
NID_certificate_issuer)
|
||||
continue;
|
||||
crl->flags |= EXFLAG_CRITICAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (j = 0; j < sk_X509_EXTENSION_num(exts); j++) {
|
||||
ext = sk_X509_EXTENSION_value(exts, j);
|
||||
if (ext->critical > 0) {
|
||||
if (OBJ_obj2nid(ext->object) == NID_certificate_issuer)
|
||||
continue;
|
||||
crl->flags |= EXFLAG_CRITICAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
return 1;
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
/* The X509_CRL structure needs a bit of customisation. Cache some extensions
|
||||
/*
|
||||
* The X509_CRL structure needs a bit of customisation. Cache some extensions
|
||||
* and hash of the whole CRL.
|
||||
*/
|
||||
static int crl_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
void *exarg)
|
||||
{
|
||||
X509_CRL *crl = (X509_CRL *)*pval;
|
||||
STACK_OF(X509_EXTENSION) *exts;
|
||||
X509_EXTENSION *ext;
|
||||
int idx;
|
||||
void *exarg)
|
||||
{
|
||||
X509_CRL *crl = (X509_CRL *)*pval;
|
||||
STACK_OF(X509_EXTENSION) *exts;
|
||||
X509_EXTENSION *ext;
|
||||
int idx;
|
||||
|
||||
switch(operation)
|
||||
{
|
||||
case ASN1_OP_NEW_POST:
|
||||
crl->idp = NULL;
|
||||
crl->akid = NULL;
|
||||
crl->flags = 0;
|
||||
crl->idp_flags = 0;
|
||||
crl->idp_reasons = CRLDP_ALL_REASONS;
|
||||
crl->meth = default_crl_method;
|
||||
crl->meth_data = NULL;
|
||||
crl->issuers = NULL;
|
||||
crl->crl_number = NULL;
|
||||
crl->base_crl_number = NULL;
|
||||
break;
|
||||
switch (operation) {
|
||||
case ASN1_OP_NEW_POST:
|
||||
crl->idp = NULL;
|
||||
crl->akid = NULL;
|
||||
crl->flags = 0;
|
||||
crl->idp_flags = 0;
|
||||
crl->idp_reasons = CRLDP_ALL_REASONS;
|
||||
crl->meth = default_crl_method;
|
||||
crl->meth_data = NULL;
|
||||
crl->issuers = NULL;
|
||||
crl->crl_number = NULL;
|
||||
crl->base_crl_number = NULL;
|
||||
break;
|
||||
|
||||
case ASN1_OP_D2I_POST:
|
||||
case ASN1_OP_D2I_POST:
|
||||
#ifndef OPENSSL_NO_SHA
|
||||
X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
|
||||
X509_CRL_digest(crl, EVP_sha1(), crl->sha1_hash, NULL);
|
||||
#endif
|
||||
crl->idp = X509_CRL_get_ext_d2i(crl,
|
||||
NID_issuing_distribution_point, NULL, NULL);
|
||||
if (crl->idp)
|
||||
setup_idp(crl, crl->idp);
|
||||
crl->idp = X509_CRL_get_ext_d2i(crl,
|
||||
NID_issuing_distribution_point, NULL,
|
||||
NULL);
|
||||
if (crl->idp)
|
||||
setup_idp(crl, crl->idp);
|
||||
|
||||
crl->akid = X509_CRL_get_ext_d2i(crl,
|
||||
NID_authority_key_identifier, NULL, NULL);
|
||||
crl->akid = X509_CRL_get_ext_d2i(crl,
|
||||
NID_authority_key_identifier, NULL,
|
||||
NULL);
|
||||
|
||||
crl->crl_number = X509_CRL_get_ext_d2i(crl,
|
||||
NID_crl_number, NULL, NULL);
|
||||
crl->crl_number = X509_CRL_get_ext_d2i(crl,
|
||||
NID_crl_number, NULL, NULL);
|
||||
|
||||
crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
|
||||
NID_delta_crl, NULL, NULL);
|
||||
/* Delta CRLs must have CRL number */
|
||||
if (crl->base_crl_number && !crl->crl_number)
|
||||
crl->flags |= EXFLAG_INVALID;
|
||||
crl->base_crl_number = X509_CRL_get_ext_d2i(crl,
|
||||
NID_delta_crl, NULL,
|
||||
NULL);
|
||||
/* Delta CRLs must have CRL number */
|
||||
if (crl->base_crl_number && !crl->crl_number)
|
||||
crl->flags |= EXFLAG_INVALID;
|
||||
|
||||
/* See if we have any unhandled critical CRL extensions and
|
||||
* indicate this in a flag. We only currently handle IDP so
|
||||
* anything else critical sets the flag.
|
||||
*
|
||||
* This code accesses the X509_CRL structure directly:
|
||||
* applications shouldn't do this.
|
||||
*/
|
||||
/*
|
||||
* See if we have any unhandled critical CRL extensions and indicate
|
||||
* this in a flag. We only currently handle IDP so anything else
|
||||
* critical sets the flag. This code accesses the X509_CRL structure
|
||||
* directly: applications shouldn't do this.
|
||||
*/
|
||||
|
||||
exts = crl->crl->extensions;
|
||||
exts = crl->crl->extensions;
|
||||
|
||||
for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++)
|
||||
{
|
||||
int nid;
|
||||
ext = sk_X509_EXTENSION_value(exts, idx);
|
||||
nid = OBJ_obj2nid(ext->object);
|
||||
if (nid == NID_freshest_crl)
|
||||
crl->flags |= EXFLAG_FRESHEST;
|
||||
if (ext->critical > 0)
|
||||
{
|
||||
/* We handle IDP and deltas */
|
||||
if ((nid == NID_issuing_distribution_point)
|
||||
|| (nid == NID_delta_crl))
|
||||
break;;
|
||||
crl->flags |= EXFLAG_CRITICAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
for (idx = 0; idx < sk_X509_EXTENSION_num(exts); idx++) {
|
||||
int nid;
|
||||
ext = sk_X509_EXTENSION_value(exts, idx);
|
||||
nid = OBJ_obj2nid(ext->object);
|
||||
if (nid == NID_freshest_crl)
|
||||
crl->flags |= EXFLAG_FRESHEST;
|
||||
if (ext->critical > 0) {
|
||||
/* We handle IDP and deltas */
|
||||
if ((nid == NID_issuing_distribution_point)
|
||||
|| (nid == NID_authority_key_identifier)
|
||||
|| (nid == NID_delta_crl))
|
||||
break;;
|
||||
crl->flags |= EXFLAG_CRITICAL;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!crl_set_issuers(crl))
|
||||
return 0;
|
||||
|
||||
if (!crl_set_issuers(crl))
|
||||
return 0;
|
||||
if (crl->meth->crl_init) {
|
||||
if (crl->meth->crl_init(crl) == 0)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
if (crl->meth->crl_init)
|
||||
{
|
||||
if (crl->meth->crl_init(crl) == 0)
|
||||
return 0;
|
||||
}
|
||||
break;
|
||||
|
||||
case ASN1_OP_FREE_POST:
|
||||
if (crl->meth->crl_free)
|
||||
{
|
||||
if (!crl->meth->crl_free(crl))
|
||||
return 0;
|
||||
}
|
||||
if (crl->akid)
|
||||
AUTHORITY_KEYID_free(crl->akid);
|
||||
if (crl->idp)
|
||||
ISSUING_DIST_POINT_free(crl->idp);
|
||||
ASN1_INTEGER_free(crl->crl_number);
|
||||
ASN1_INTEGER_free(crl->base_crl_number);
|
||||
sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
case ASN1_OP_FREE_POST:
|
||||
if (crl->meth->crl_free) {
|
||||
if (!crl->meth->crl_free(crl))
|
||||
return 0;
|
||||
}
|
||||
if (crl->akid)
|
||||
AUTHORITY_KEYID_free(crl->akid);
|
||||
if (crl->idp)
|
||||
ISSUING_DIST_POINT_free(crl->idp);
|
||||
ASN1_INTEGER_free(crl->crl_number);
|
||||
ASN1_INTEGER_free(crl->base_crl_number);
|
||||
sk_GENERAL_NAMES_pop_free(crl->issuers, GENERAL_NAMES_free);
|
||||
break;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
/* Convert IDP into a more convenient form */
|
||||
|
||||
static void setup_idp(X509_CRL *crl, ISSUING_DIST_POINT *idp)
|
||||
{
|
||||
int idp_only = 0;
|
||||
/* Set various flags according to IDP */
|
||||
crl->idp_flags |= IDP_PRESENT;
|
||||
if (idp->onlyuser > 0)
|
||||
{
|
||||
idp_only++;
|
||||
crl->idp_flags |= IDP_ONLYUSER;
|
||||
}
|
||||
if (idp->onlyCA > 0)
|
||||
{
|
||||
idp_only++;
|
||||
crl->idp_flags |= IDP_ONLYCA;
|
||||
}
|
||||
if (idp->onlyattr > 0)
|
||||
{
|
||||
idp_only++;
|
||||
crl->idp_flags |= IDP_ONLYATTR;
|
||||
}
|
||||
{
|
||||
int idp_only = 0;
|
||||
/* Set various flags according to IDP */
|
||||
crl->idp_flags |= IDP_PRESENT;
|
||||
if (idp->onlyuser > 0) {
|
||||
idp_only++;
|
||||
crl->idp_flags |= IDP_ONLYUSER;
|
||||
}
|
||||
if (idp->onlyCA > 0) {
|
||||
idp_only++;
|
||||
crl->idp_flags |= IDP_ONLYCA;
|
||||
}
|
||||
if (idp->onlyattr > 0) {
|
||||
idp_only++;
|
||||
crl->idp_flags |= IDP_ONLYATTR;
|
||||
}
|
||||
|
||||
if (idp_only > 1)
|
||||
crl->idp_flags |= IDP_INVALID;
|
||||
if (idp_only > 1)
|
||||
crl->idp_flags |= IDP_INVALID;
|
||||
|
||||
if (idp->indirectCRL > 0)
|
||||
crl->idp_flags |= IDP_INDIRECT;
|
||||
if (idp->indirectCRL > 0)
|
||||
crl->idp_flags |= IDP_INDIRECT;
|
||||
|
||||
if (idp->onlysomereasons)
|
||||
{
|
||||
crl->idp_flags |= IDP_REASONS;
|
||||
if (idp->onlysomereasons->length > 0)
|
||||
crl->idp_reasons = idp->onlysomereasons->data[0];
|
||||
if (idp->onlysomereasons->length > 1)
|
||||
crl->idp_reasons |=
|
||||
(idp->onlysomereasons->data[1] << 8);
|
||||
crl->idp_reasons &= CRLDP_ALL_REASONS;
|
||||
}
|
||||
if (idp->onlysomereasons) {
|
||||
crl->idp_flags |= IDP_REASONS;
|
||||
if (idp->onlysomereasons->length > 0)
|
||||
crl->idp_reasons = idp->onlysomereasons->data[0];
|
||||
if (idp->onlysomereasons->length > 1)
|
||||
crl->idp_reasons |= (idp->onlysomereasons->data[1] << 8);
|
||||
crl->idp_reasons &= CRLDP_ALL_REASONS;
|
||||
}
|
||||
|
||||
DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
|
||||
}
|
||||
DIST_POINT_set_dpname(idp->distpoint, X509_CRL_get_issuer(crl));
|
||||
}
|
||||
|
||||
ASN1_SEQUENCE_ref(X509_CRL, crl_cb, CRYPTO_LOCK_X509_CRL) = {
|
||||
ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
|
||||
ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
|
||||
ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
|
||||
ASN1_SIMPLE(X509_CRL, crl, X509_CRL_INFO),
|
||||
ASN1_SIMPLE(X509_CRL, sig_alg, X509_ALGOR),
|
||||
ASN1_SIMPLE(X509_CRL, signature, ASN1_BIT_STRING)
|
||||
} ASN1_SEQUENCE_END_ref(X509_CRL, X509_CRL)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_REVOKED)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_CRL_INFO)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_CRL)
|
||||
|
||||
IMPLEMENT_ASN1_DUP_FUNCTION(X509_CRL)
|
||||
|
||||
static int X509_REVOKED_cmp(const X509_REVOKED * const *a,
|
||||
const X509_REVOKED * const *b)
|
||||
{
|
||||
return(ASN1_STRING_cmp(
|
||||
(ASN1_STRING *)(*a)->serialNumber,
|
||||
(ASN1_STRING *)(*b)->serialNumber));
|
||||
}
|
||||
static int X509_REVOKED_cmp(const X509_REVOKED *const *a,
|
||||
const X509_REVOKED *const *b)
|
||||
{
|
||||
return (ASN1_STRING_cmp((ASN1_STRING *)(*a)->serialNumber,
|
||||
(ASN1_STRING *)(*b)->serialNumber));
|
||||
}
|
||||
|
||||
int X509_CRL_add0_revoked(X509_CRL *crl, X509_REVOKED *rev)
|
||||
{
|
||||
X509_CRL_INFO *inf;
|
||||
inf = crl->crl;
|
||||
if(!inf->revoked)
|
||||
inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
|
||||
if(!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
|
||||
ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
inf->enc.modified = 1;
|
||||
return 1;
|
||||
X509_CRL_INFO *inf;
|
||||
inf = crl->crl;
|
||||
if (!inf->revoked)
|
||||
inf->revoked = sk_X509_REVOKED_new(X509_REVOKED_cmp);
|
||||
if (!inf->revoked || !sk_X509_REVOKED_push(inf->revoked, rev)) {
|
||||
ASN1err(ASN1_F_X509_CRL_ADD0_REVOKED, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
inf->enc.modified = 1;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int X509_CRL_verify(X509_CRL *crl, EVP_PKEY *r)
|
||||
{
|
||||
if (crl->meth->crl_verify)
|
||||
return crl->meth->crl_verify(crl, r);
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
if (crl->meth->crl_verify)
|
||||
return crl->meth->crl_verify(crl, r);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int X509_CRL_get0_by_serial(X509_CRL *crl,
|
||||
X509_REVOKED **ret, ASN1_INTEGER *serial)
|
||||
{
|
||||
if (crl->meth->crl_lookup)
|
||||
return crl->meth->crl_lookup(crl, ret, serial, NULL);
|
||||
return 0;
|
||||
}
|
||||
X509_REVOKED **ret, ASN1_INTEGER *serial)
|
||||
{
|
||||
if (crl->meth->crl_lookup)
|
||||
return crl->meth->crl_lookup(crl, ret, serial, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
int X509_CRL_get0_by_cert(X509_CRL *crl, X509_REVOKED **ret, X509 *x)
|
||||
{
|
||||
if (crl->meth->crl_lookup)
|
||||
return crl->meth->crl_lookup(crl, ret,
|
||||
X509_get_serialNumber(x),
|
||||
X509_get_issuer_name(x));
|
||||
return 0;
|
||||
}
|
||||
{
|
||||
if (crl->meth->crl_lookup)
|
||||
return crl->meth->crl_lookup(crl, ret,
|
||||
X509_get_serialNumber(x),
|
||||
X509_get_issuer_name(x));
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int def_crl_verify(X509_CRL *crl, EVP_PKEY *r)
|
||||
{
|
||||
return(ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
|
||||
crl->sig_alg, crl->signature,crl->crl,r));
|
||||
}
|
||||
{
|
||||
return (ASN1_item_verify(ASN1_ITEM_rptr(X509_CRL_INFO),
|
||||
crl->sig_alg, crl->signature, crl->crl, r));
|
||||
}
|
||||
|
||||
static int crl_revoked_issuer_match(X509_CRL *crl, X509_NAME *nm,
|
||||
X509_REVOKED *rev)
|
||||
{
|
||||
int i;
|
||||
X509_REVOKED *rev)
|
||||
{
|
||||
int i;
|
||||
|
||||
if (!rev->issuer)
|
||||
{
|
||||
if (!nm)
|
||||
return 1;
|
||||
if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
if (!rev->issuer) {
|
||||
if (!nm)
|
||||
return 1;
|
||||
if (!X509_NAME_cmp(nm, X509_CRL_get_issuer(crl)))
|
||||
return 1;
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (!nm)
|
||||
nm = X509_CRL_get_issuer(crl);
|
||||
if (!nm)
|
||||
nm = X509_CRL_get_issuer(crl);
|
||||
|
||||
for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++)
|
||||
{
|
||||
GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
|
||||
if (gen->type != GEN_DIRNAME)
|
||||
continue;
|
||||
if (!X509_NAME_cmp(nm, gen->d.directoryName))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
for (i = 0; i < sk_GENERAL_NAME_num(rev->issuer); i++) {
|
||||
GENERAL_NAME *gen = sk_GENERAL_NAME_value(rev->issuer, i);
|
||||
if (gen->type != GEN_DIRNAME)
|
||||
continue;
|
||||
if (!X509_NAME_cmp(nm, gen->d.directoryName))
|
||||
return 1;
|
||||
}
|
||||
return 0;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int def_crl_lookup(X509_CRL *crl,
|
||||
X509_REVOKED **ret, ASN1_INTEGER *serial, X509_NAME *issuer)
|
||||
{
|
||||
X509_REVOKED rtmp, *rev;
|
||||
int idx;
|
||||
rtmp.serialNumber = serial;
|
||||
/* Sort revoked into serial number order if not already sorted.
|
||||
* Do this under a lock to avoid race condition.
|
||||
*/
|
||||
if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked))
|
||||
{
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
|
||||
sk_X509_REVOKED_sort(crl->crl->revoked);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
|
||||
}
|
||||
idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
|
||||
if(idx < 0)
|
||||
return 0;
|
||||
/* Need to look for matching name */
|
||||
for(;idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++)
|
||||
{
|
||||
rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
|
||||
if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
|
||||
return 0;
|
||||
if (crl_revoked_issuer_match(crl, issuer, rev))
|
||||
{
|
||||
if (ret)
|
||||
*ret = rev;
|
||||
if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
X509_REVOKED **ret, ASN1_INTEGER *serial,
|
||||
X509_NAME *issuer)
|
||||
{
|
||||
X509_REVOKED rtmp, *rev;
|
||||
int idx;
|
||||
rtmp.serialNumber = serial;
|
||||
/*
|
||||
* Sort revoked into serial number order if not already sorted. Do this
|
||||
* under a lock to avoid race condition.
|
||||
*/
|
||||
if (!sk_X509_REVOKED_is_sorted(crl->crl->revoked)) {
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_X509_CRL);
|
||||
sk_X509_REVOKED_sort(crl->crl->revoked);
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_X509_CRL);
|
||||
}
|
||||
idx = sk_X509_REVOKED_find(crl->crl->revoked, &rtmp);
|
||||
if (idx < 0)
|
||||
return 0;
|
||||
/* Need to look for matching name */
|
||||
for (; idx < sk_X509_REVOKED_num(crl->crl->revoked); idx++) {
|
||||
rev = sk_X509_REVOKED_value(crl->crl->revoked, idx);
|
||||
if (ASN1_INTEGER_cmp(rev->serialNumber, serial))
|
||||
return 0;
|
||||
if (crl_revoked_issuer_match(crl, issuer, rev)) {
|
||||
if (ret)
|
||||
*ret = rev;
|
||||
if (rev->reason == CRL_REASON_REMOVE_FROM_CRL)
|
||||
return 2;
|
||||
return 1;
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void X509_CRL_set_default_method(const X509_CRL_METHOD *meth)
|
||||
{
|
||||
if (meth == NULL)
|
||||
default_crl_method = &int_crl_meth;
|
||||
else
|
||||
default_crl_method = meth;
|
||||
}
|
||||
{
|
||||
if (meth == NULL)
|
||||
default_crl_method = &int_crl_meth;
|
||||
else
|
||||
default_crl_method = meth;
|
||||
}
|
||||
|
||||
X509_CRL_METHOD *X509_CRL_METHOD_new(
|
||||
int (*crl_init)(X509_CRL *crl),
|
||||
int (*crl_free)(X509_CRL *crl),
|
||||
int (*crl_lookup)(X509_CRL *crl, X509_REVOKED **ret,
|
||||
ASN1_INTEGER *ser, X509_NAME *issuer),
|
||||
int (*crl_verify)(X509_CRL *crl, EVP_PKEY *pk))
|
||||
{
|
||||
X509_CRL_METHOD *m;
|
||||
m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
|
||||
if (!m)
|
||||
return NULL;
|
||||
m->crl_init = crl_init;
|
||||
m->crl_free = crl_free;
|
||||
m->crl_lookup = crl_lookup;
|
||||
m->crl_verify = crl_verify;
|
||||
m->flags = X509_CRL_METHOD_DYNAMIC;
|
||||
return m;
|
||||
}
|
||||
X509_CRL_METHOD *X509_CRL_METHOD_new(int (*crl_init) (X509_CRL *crl),
|
||||
int (*crl_free) (X509_CRL *crl),
|
||||
int (*crl_lookup) (X509_CRL *crl,
|
||||
X509_REVOKED **ret,
|
||||
ASN1_INTEGER *ser,
|
||||
X509_NAME *issuer),
|
||||
int (*crl_verify) (X509_CRL *crl,
|
||||
EVP_PKEY *pk))
|
||||
{
|
||||
X509_CRL_METHOD *m;
|
||||
m = OPENSSL_malloc(sizeof(X509_CRL_METHOD));
|
||||
if (!m)
|
||||
return NULL;
|
||||
m->crl_init = crl_init;
|
||||
m->crl_free = crl_free;
|
||||
m->crl_lookup = crl_lookup;
|
||||
m->crl_verify = crl_verify;
|
||||
m->flags = X509_CRL_METHOD_DYNAMIC;
|
||||
return m;
|
||||
}
|
||||
|
||||
void X509_CRL_METHOD_free(X509_CRL_METHOD *m)
|
||||
{
|
||||
if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
|
||||
return;
|
||||
OPENSSL_free(m);
|
||||
}
|
||||
{
|
||||
if (!(m->flags & X509_CRL_METHOD_DYNAMIC))
|
||||
return;
|
||||
OPENSSL_free(m);
|
||||
}
|
||||
|
||||
void X509_CRL_set_meth_data(X509_CRL *crl, void *dat)
|
||||
{
|
||||
crl->meth_data = dat;
|
||||
}
|
||||
{
|
||||
crl->meth_data = dat;
|
||||
}
|
||||
|
||||
void *X509_CRL_get_meth_data(X509_CRL *crl)
|
||||
{
|
||||
return crl->meth_data;
|
||||
}
|
||||
{
|
||||
return crl->meth_data;
|
||||
}
|
||||
|
||||
IMPLEMENT_STACK_OF(X509_REVOKED)
|
||||
|
||||
IMPLEMENT_ASN1_SET_OF(X509_REVOKED)
|
||||
|
||||
IMPLEMENT_STACK_OF(X509_CRL)
|
||||
|
||||
IMPLEMENT_ASN1_SET_OF(X509_CRL)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* x_exten.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2000.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2000.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -62,13 +63,13 @@
|
||||
#include <openssl/asn1t.h>
|
||||
|
||||
ASN1_SEQUENCE(X509_EXTENSION) = {
|
||||
ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
|
||||
ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
|
||||
ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
|
||||
ASN1_SIMPLE(X509_EXTENSION, object, ASN1_OBJECT),
|
||||
ASN1_OPT(X509_EXTENSION, critical, ASN1_BOOLEAN),
|
||||
ASN1_SIMPLE(X509_EXTENSION, value, ASN1_OCTET_STRING)
|
||||
} ASN1_SEQUENCE_END(X509_EXTENSION)
|
||||
|
||||
ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
|
||||
ASN1_ITEM_TEMPLATE(X509_EXTENSIONS) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Extension, X509_EXTENSION)
|
||||
ASN1_ITEM_TEMPLATE_END(X509_EXTENSIONS)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_EXTENSION)
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -63,52 +63,55 @@
|
||||
#include <openssl/x509.h>
|
||||
|
||||
X509_INFO *X509_INFO_new(void)
|
||||
{
|
||||
X509_INFO *ret=NULL;
|
||||
{
|
||||
X509_INFO *ret = NULL;
|
||||
|
||||
ret=(X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO));
|
||||
if (ret == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_X509_INFO_NEW,ERR_R_MALLOC_FAILURE);
|
||||
return(NULL);
|
||||
}
|
||||
|
||||
ret->enc_cipher.cipher=NULL;
|
||||
ret->enc_len=0;
|
||||
ret->enc_data=NULL;
|
||||
|
||||
ret->references=1;
|
||||
ret->x509=NULL;
|
||||
ret->crl=NULL;
|
||||
ret->x_pkey=NULL;
|
||||
return(ret);
|
||||
}
|
||||
ret = (X509_INFO *)OPENSSL_malloc(sizeof(X509_INFO));
|
||||
if (ret == NULL) {
|
||||
ASN1err(ASN1_F_X509_INFO_NEW, ERR_R_MALLOC_FAILURE);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
ret->enc_cipher.cipher = NULL;
|
||||
ret->enc_len = 0;
|
||||
ret->enc_data = NULL;
|
||||
|
||||
ret->references = 1;
|
||||
ret->x509 = NULL;
|
||||
ret->crl = NULL;
|
||||
ret->x_pkey = NULL;
|
||||
return (ret);
|
||||
}
|
||||
|
||||
void X509_INFO_free(X509_INFO *x)
|
||||
{
|
||||
int i;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (x == NULL) return;
|
||||
if (x == NULL)
|
||||
return;
|
||||
|
||||
i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_X509_INFO);
|
||||
i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_INFO);
|
||||
#ifdef REF_PRINT
|
||||
REF_PRINT("X509_INFO",x);
|
||||
REF_PRINT("X509_INFO", x);
|
||||
#endif
|
||||
if (i > 0) return;
|
||||
if (i > 0)
|
||||
return;
|
||||
#ifdef REF_CHECK
|
||||
if (i < 0)
|
||||
{
|
||||
fprintf(stderr,"X509_INFO_free, bad reference count\n");
|
||||
abort();
|
||||
}
|
||||
if (i < 0) {
|
||||
fprintf(stderr, "X509_INFO_free, bad reference count\n");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (x->x509 != NULL) X509_free(x->x509);
|
||||
if (x->crl != NULL) X509_CRL_free(x->crl);
|
||||
if (x->x_pkey != NULL) X509_PKEY_free(x->x_pkey);
|
||||
if (x->enc_data != NULL) OPENSSL_free(x->enc_data);
|
||||
OPENSSL_free(x);
|
||||
}
|
||||
if (x->x509 != NULL)
|
||||
X509_free(x->x509);
|
||||
if (x->crl != NULL)
|
||||
X509_CRL_free(x->crl);
|
||||
if (x->x_pkey != NULL)
|
||||
X509_PKEY_free(x->x_pkey);
|
||||
if (x->enc_data != NULL)
|
||||
OPENSSL_free(x->enc_data);
|
||||
OPENSSL_free(x);
|
||||
}
|
||||
|
||||
IMPLEMENT_STACK_OF(X509_INFO)
|
||||
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* x_long.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2000.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2000.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2000 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -61,119 +62,135 @@
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/bn.h>
|
||||
|
||||
/* Custom primitive type for long handling. This converts between an ASN1_INTEGER
|
||||
* and a long directly.
|
||||
/*
|
||||
* Custom primitive type for long handling. This converts between an
|
||||
* ASN1_INTEGER and a long directly.
|
||||
*/
|
||||
|
||||
|
||||
static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it);
|
||||
static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it);
|
||||
|
||||
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it);
|
||||
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len, int utype, char *free_cont, const ASN1_ITEM *it);
|
||||
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it, int indent, const ASN1_PCTX *pctx);
|
||||
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
|
||||
const ASN1_ITEM *it);
|
||||
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
|
||||
int utype, char *free_cont, const ASN1_ITEM *it);
|
||||
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
int indent, const ASN1_PCTX *pctx);
|
||||
|
||||
static ASN1_PRIMITIVE_FUNCS long_pf = {
|
||||
NULL, 0,
|
||||
long_new,
|
||||
long_free,
|
||||
long_free, /* Clear should set to initial value */
|
||||
long_c2i,
|
||||
long_i2c,
|
||||
long_print
|
||||
NULL, 0,
|
||||
long_new,
|
||||
long_free,
|
||||
long_free, /* Clear should set to initial value */
|
||||
long_c2i,
|
||||
long_i2c,
|
||||
long_print
|
||||
};
|
||||
|
||||
ASN1_ITEM_start(LONG)
|
||||
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
|
||||
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, ASN1_LONG_UNDEF, "LONG"
|
||||
ASN1_ITEM_end(LONG)
|
||||
|
||||
ASN1_ITEM_start(ZLONG)
|
||||
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
|
||||
ASN1_ITYPE_PRIMITIVE, V_ASN1_INTEGER, NULL, 0, &long_pf, 0, "ZLONG"
|
||||
ASN1_ITEM_end(ZLONG)
|
||||
|
||||
static int long_new(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
*(long *)pval = it->size;
|
||||
return 1;
|
||||
*(long *)pval = it->size;
|
||||
return 1;
|
||||
}
|
||||
|
||||
static void long_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
*(long *)pval = it->size;
|
||||
*(long *)pval = it->size;
|
||||
}
|
||||
|
||||
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype, const ASN1_ITEM *it)
|
||||
static int long_i2c(ASN1_VALUE **pval, unsigned char *cont, int *putype,
|
||||
const ASN1_ITEM *it)
|
||||
{
|
||||
long ltmp;
|
||||
unsigned long utmp;
|
||||
int clen, pad, i;
|
||||
/* this exists to bypass broken gcc optimization */
|
||||
char *cp = (char *)pval;
|
||||
long ltmp;
|
||||
unsigned long utmp;
|
||||
int clen, pad, i;
|
||||
/* this exists to bypass broken gcc optimization */
|
||||
char *cp = (char *)pval;
|
||||
|
||||
/* use memcpy, because we may not be long aligned */
|
||||
memcpy(<mp, cp, sizeof(long));
|
||||
/* use memcpy, because we may not be long aligned */
|
||||
memcpy(<mp, cp, sizeof(long));
|
||||
|
||||
if(ltmp == it->size) return -1;
|
||||
/* Convert the long to positive: we subtract one if negative so
|
||||
* we can cleanly handle the padding if only the MSB of the leading
|
||||
* octet is set.
|
||||
*/
|
||||
if(ltmp < 0) utmp = -ltmp - 1;
|
||||
else utmp = ltmp;
|
||||
clen = BN_num_bits_word(utmp);
|
||||
/* If MSB of leading octet set we need to pad */
|
||||
if(!(clen & 0x7)) pad = 1;
|
||||
else pad = 0;
|
||||
if (ltmp == it->size)
|
||||
return -1;
|
||||
/*
|
||||
* Convert the long to positive: we subtract one if negative so we can
|
||||
* cleanly handle the padding if only the MSB of the leading octet is
|
||||
* set.
|
||||
*/
|
||||
if (ltmp < 0)
|
||||
utmp = -ltmp - 1;
|
||||
else
|
||||
utmp = ltmp;
|
||||
clen = BN_num_bits_word(utmp);
|
||||
/* If MSB of leading octet set we need to pad */
|
||||
if (!(clen & 0x7))
|
||||
pad = 1;
|
||||
else
|
||||
pad = 0;
|
||||
|
||||
/* Convert number of bits to number of octets */
|
||||
clen = (clen + 7) >> 3;
|
||||
/* Convert number of bits to number of octets */
|
||||
clen = (clen + 7) >> 3;
|
||||
|
||||
if(cont) {
|
||||
if(pad) *cont++ = (ltmp < 0) ? 0xff : 0;
|
||||
for(i = clen - 1; i >= 0; i--) {
|
||||
cont[i] = (unsigned char)(utmp & 0xff);
|
||||
if(ltmp < 0) cont[i] ^= 0xff;
|
||||
utmp >>= 8;
|
||||
}
|
||||
}
|
||||
return clen + pad;
|
||||
if (cont) {
|
||||
if (pad)
|
||||
*cont++ = (ltmp < 0) ? 0xff : 0;
|
||||
for (i = clen - 1; i >= 0; i--) {
|
||||
cont[i] = (unsigned char)(utmp & 0xff);
|
||||
if (ltmp < 0)
|
||||
cont[i] ^= 0xff;
|
||||
utmp >>= 8;
|
||||
}
|
||||
}
|
||||
return clen + pad;
|
||||
}
|
||||
|
||||
static int long_c2i(ASN1_VALUE **pval, const unsigned char *cont, int len,
|
||||
int utype, char *free_cont, const ASN1_ITEM *it)
|
||||
int utype, char *free_cont, const ASN1_ITEM *it)
|
||||
{
|
||||
int neg, i;
|
||||
long ltmp;
|
||||
unsigned long utmp = 0;
|
||||
char *cp = (char *)pval;
|
||||
if(len > (int)sizeof(long)) {
|
||||
ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
|
||||
return 0;
|
||||
}
|
||||
/* Is it negative? */
|
||||
if(len && (cont[0] & 0x80)) neg = 1;
|
||||
else neg = 0;
|
||||
utmp = 0;
|
||||
for(i = 0; i < len; i++) {
|
||||
utmp <<= 8;
|
||||
if(neg) utmp |= cont[i] ^ 0xff;
|
||||
else utmp |= cont[i];
|
||||
}
|
||||
ltmp = (long)utmp;
|
||||
if(neg) {
|
||||
ltmp++;
|
||||
ltmp = -ltmp;
|
||||
}
|
||||
if(ltmp == it->size) {
|
||||
ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
|
||||
return 0;
|
||||
}
|
||||
memcpy(cp, <mp, sizeof(long));
|
||||
return 1;
|
||||
int neg, i;
|
||||
long ltmp;
|
||||
unsigned long utmp = 0;
|
||||
char *cp = (char *)pval;
|
||||
if (len > (int)sizeof(long)) {
|
||||
ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
|
||||
return 0;
|
||||
}
|
||||
/* Is it negative? */
|
||||
if (len && (cont[0] & 0x80))
|
||||
neg = 1;
|
||||
else
|
||||
neg = 0;
|
||||
utmp = 0;
|
||||
for (i = 0; i < len; i++) {
|
||||
utmp <<= 8;
|
||||
if (neg)
|
||||
utmp |= cont[i] ^ 0xff;
|
||||
else
|
||||
utmp |= cont[i];
|
||||
}
|
||||
ltmp = (long)utmp;
|
||||
if (neg) {
|
||||
ltmp++;
|
||||
ltmp = -ltmp;
|
||||
}
|
||||
if (ltmp == it->size) {
|
||||
ASN1err(ASN1_F_LONG_C2I, ASN1_R_INTEGER_TOO_LARGE_FOR_LONG);
|
||||
return 0;
|
||||
}
|
||||
memcpy(cp, <mp, sizeof(long));
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int long_print(BIO *out, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
int indent, const ASN1_PCTX *pctx)
|
||||
{
|
||||
return BIO_printf(out, "%ld\n", *(long *)pval);
|
||||
}
|
||||
int indent, const ASN1_PCTX *pctx)
|
||||
{
|
||||
return BIO_printf(out, "%ld\n", *(long *)pval);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -67,453 +67,461 @@ typedef STACK_OF(X509_NAME_ENTRY) STACK_OF_X509_NAME_ENTRY;
|
||||
DECLARE_STACK_OF(STACK_OF_X509_NAME_ENTRY)
|
||||
|
||||
static int x509_name_ex_d2i(ASN1_VALUE **val,
|
||||
const unsigned char **in, long len,
|
||||
const ASN1_ITEM *it,
|
||||
int tag, int aclass, char opt, ASN1_TLC *ctx);
|
||||
const unsigned char **in, long len,
|
||||
const ASN1_ITEM *it,
|
||||
int tag, int aclass, char opt, ASN1_TLC *ctx);
|
||||
|
||||
static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
|
||||
const ASN1_ITEM *it, int tag, int aclass);
|
||||
const ASN1_ITEM *it, int tag, int aclass);
|
||||
static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it);
|
||||
static void x509_name_ex_free(ASN1_VALUE **val, const ASN1_ITEM *it);
|
||||
|
||||
static int x509_name_encode(X509_NAME *a);
|
||||
static int x509_name_canon(X509_NAME *a);
|
||||
static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in);
|
||||
static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname,
|
||||
unsigned char **in);
|
||||
|
||||
static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * intname,
|
||||
unsigned char **in);
|
||||
|
||||
static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
|
||||
int indent,
|
||||
const char *fname,
|
||||
const ASN1_PCTX *pctx);
|
||||
int indent,
|
||||
const char *fname, const ASN1_PCTX *pctx);
|
||||
|
||||
ASN1_SEQUENCE(X509_NAME_ENTRY) = {
|
||||
ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
|
||||
ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
|
||||
ASN1_SIMPLE(X509_NAME_ENTRY, object, ASN1_OBJECT),
|
||||
ASN1_SIMPLE(X509_NAME_ENTRY, value, ASN1_PRINTABLE)
|
||||
} ASN1_SEQUENCE_END(X509_NAME_ENTRY)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_NAME_ENTRY)
|
||||
IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME_ENTRY)
|
||||
|
||||
/* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY }
|
||||
* so declare two template wrappers for this
|
||||
/*
|
||||
* For the "Name" type we need a SEQUENCE OF { SET OF X509_NAME_ENTRY } so
|
||||
* declare two template wrappers for this
|
||||
*/
|
||||
|
||||
ASN1_ITEM_TEMPLATE(X509_NAME_ENTRIES) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SET_OF, 0, RDNS, X509_NAME_ENTRY)
|
||||
ASN1_ITEM_TEMPLATE_END(X509_NAME_ENTRIES)
|
||||
|
||||
ASN1_ITEM_TEMPLATE(X509_NAME_INTERNAL) =
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
|
||||
ASN1_EX_TEMPLATE_TYPE(ASN1_TFLG_SEQUENCE_OF, 0, Name, X509_NAME_ENTRIES)
|
||||
ASN1_ITEM_TEMPLATE_END(X509_NAME_INTERNAL)
|
||||
|
||||
/* Normally that's where it would end: we'd have two nested STACK structures
|
||||
/*
|
||||
* Normally that's where it would end: we'd have two nested STACK structures
|
||||
* representing the ASN1. Unfortunately X509_NAME uses a completely different
|
||||
* form and caches encodings so we have to process the internal form and convert
|
||||
* to the external form.
|
||||
* form and caches encodings so we have to process the internal form and
|
||||
* convert to the external form.
|
||||
*/
|
||||
|
||||
const ASN1_EXTERN_FUNCS x509_name_ff = {
|
||||
NULL,
|
||||
x509_name_ex_new,
|
||||
x509_name_ex_free,
|
||||
0, /* Default clear behaviour is OK */
|
||||
x509_name_ex_d2i,
|
||||
x509_name_ex_i2d,
|
||||
x509_name_ex_print
|
||||
NULL,
|
||||
x509_name_ex_new,
|
||||
x509_name_ex_free,
|
||||
0, /* Default clear behaviour is OK */
|
||||
x509_name_ex_d2i,
|
||||
x509_name_ex_i2d,
|
||||
x509_name_ex_print
|
||||
};
|
||||
|
||||
IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
|
||||
IMPLEMENT_EXTERN_ASN1(X509_NAME, V_ASN1_SEQUENCE, x509_name_ff)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_NAME)
|
||||
|
||||
IMPLEMENT_ASN1_DUP_FUNCTION(X509_NAME)
|
||||
|
||||
static int x509_name_ex_new(ASN1_VALUE **val, const ASN1_ITEM *it)
|
||||
{
|
||||
X509_NAME *ret = NULL;
|
||||
ret = OPENSSL_malloc(sizeof(X509_NAME));
|
||||
if(!ret) goto memerr;
|
||||
if ((ret->entries=sk_X509_NAME_ENTRY_new_null()) == NULL)
|
||||
goto memerr;
|
||||
if((ret->bytes = BUF_MEM_new()) == NULL) goto memerr;
|
||||
ret->canon_enc = NULL;
|
||||
ret->canon_enclen = 0;
|
||||
ret->modified=1;
|
||||
*val = (ASN1_VALUE *)ret;
|
||||
return 1;
|
||||
X509_NAME *ret = NULL;
|
||||
ret = OPENSSL_malloc(sizeof(X509_NAME));
|
||||
if (!ret)
|
||||
goto memerr;
|
||||
if ((ret->entries = sk_X509_NAME_ENTRY_new_null()) == NULL)
|
||||
goto memerr;
|
||||
if ((ret->bytes = BUF_MEM_new()) == NULL)
|
||||
goto memerr;
|
||||
ret->canon_enc = NULL;
|
||||
ret->canon_enclen = 0;
|
||||
ret->modified = 1;
|
||||
*val = (ASN1_VALUE *)ret;
|
||||
return 1;
|
||||
|
||||
memerr:
|
||||
ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
if (ret)
|
||||
{
|
||||
if (ret->entries)
|
||||
sk_X509_NAME_ENTRY_free(ret->entries);
|
||||
OPENSSL_free(ret);
|
||||
}
|
||||
return 0;
|
||||
ASN1err(ASN1_F_X509_NAME_EX_NEW, ERR_R_MALLOC_FAILURE);
|
||||
if (ret) {
|
||||
if (ret->entries)
|
||||
sk_X509_NAME_ENTRY_free(ret->entries);
|
||||
OPENSSL_free(ret);
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void x509_name_ex_free(ASN1_VALUE **pval, const ASN1_ITEM *it)
|
||||
{
|
||||
X509_NAME *a;
|
||||
if(!pval || !*pval)
|
||||
return;
|
||||
a = (X509_NAME *)*pval;
|
||||
X509_NAME *a;
|
||||
if (!pval || !*pval)
|
||||
return;
|
||||
a = (X509_NAME *)*pval;
|
||||
|
||||
BUF_MEM_free(a->bytes);
|
||||
sk_X509_NAME_ENTRY_pop_free(a->entries,X509_NAME_ENTRY_free);
|
||||
if (a->canon_enc)
|
||||
OPENSSL_free(a->canon_enc);
|
||||
OPENSSL_free(a);
|
||||
*pval = NULL;
|
||||
BUF_MEM_free(a->bytes);
|
||||
sk_X509_NAME_ENTRY_pop_free(a->entries, X509_NAME_ENTRY_free);
|
||||
if (a->canon_enc)
|
||||
OPENSSL_free(a->canon_enc);
|
||||
OPENSSL_free(a);
|
||||
*pval = NULL;
|
||||
}
|
||||
|
||||
static int x509_name_ex_d2i(ASN1_VALUE **val,
|
||||
const unsigned char **in, long len, const ASN1_ITEM *it,
|
||||
int tag, int aclass, char opt, ASN1_TLC *ctx)
|
||||
const unsigned char **in, long len,
|
||||
const ASN1_ITEM *it, int tag, int aclass,
|
||||
char opt, ASN1_TLC *ctx)
|
||||
{
|
||||
const unsigned char *p = *in, *q;
|
||||
union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
|
||||
ASN1_VALUE *a; } intname = {NULL};
|
||||
union { X509_NAME *x; ASN1_VALUE *a; } nm = {NULL};
|
||||
int i, j, ret;
|
||||
STACK_OF(X509_NAME_ENTRY) *entries;
|
||||
X509_NAME_ENTRY *entry;
|
||||
q = p;
|
||||
const unsigned char *p = *in, *q;
|
||||
union {
|
||||
STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
|
||||
ASN1_VALUE *a;
|
||||
} intname = {
|
||||
NULL
|
||||
};
|
||||
union {
|
||||
X509_NAME *x;
|
||||
ASN1_VALUE *a;
|
||||
} nm = {
|
||||
NULL
|
||||
};
|
||||
int i, j, ret;
|
||||
STACK_OF(X509_NAME_ENTRY) *entries;
|
||||
X509_NAME_ENTRY *entry;
|
||||
q = p;
|
||||
|
||||
/* Get internal representation of Name */
|
||||
ret = ASN1_item_ex_d2i(&intname.a,
|
||||
&p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
|
||||
tag, aclass, opt, ctx);
|
||||
|
||||
if(ret <= 0) return ret;
|
||||
/* Get internal representation of Name */
|
||||
ret = ASN1_item_ex_d2i(&intname.a,
|
||||
&p, len, ASN1_ITEM_rptr(X509_NAME_INTERNAL),
|
||||
tag, aclass, opt, ctx);
|
||||
|
||||
if(*val) x509_name_ex_free(val, NULL);
|
||||
if(!x509_name_ex_new(&nm.a, NULL)) goto err;
|
||||
/* We've decoded it: now cache encoding */
|
||||
if(!BUF_MEM_grow(nm.x->bytes, p - q)) goto err;
|
||||
memcpy(nm.x->bytes->data, q, p - q);
|
||||
if (ret <= 0)
|
||||
return ret;
|
||||
|
||||
/* Convert internal representation to X509_NAME structure */
|
||||
for(i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
|
||||
entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
|
||||
for(j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
|
||||
entry = sk_X509_NAME_ENTRY_value(entries, j);
|
||||
entry->set = i;
|
||||
if(!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
|
||||
goto err;
|
||||
}
|
||||
sk_X509_NAME_ENTRY_free(entries);
|
||||
}
|
||||
sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
|
||||
ret = x509_name_canon(nm.x);
|
||||
if (!ret)
|
||||
goto err;
|
||||
nm.x->modified = 0;
|
||||
*val = nm.a;
|
||||
*in = p;
|
||||
return ret;
|
||||
err:
|
||||
if (nm.x != NULL)
|
||||
X509_NAME_free(nm.x);
|
||||
ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
|
||||
return 0;
|
||||
if (*val)
|
||||
x509_name_ex_free(val, NULL);
|
||||
if (!x509_name_ex_new(&nm.a, NULL))
|
||||
goto err;
|
||||
/* We've decoded it: now cache encoding */
|
||||
if (!BUF_MEM_grow(nm.x->bytes, p - q))
|
||||
goto err;
|
||||
memcpy(nm.x->bytes->data, q, p - q);
|
||||
|
||||
/* Convert internal representation to X509_NAME structure */
|
||||
for (i = 0; i < sk_STACK_OF_X509_NAME_ENTRY_num(intname.s); i++) {
|
||||
entries = sk_STACK_OF_X509_NAME_ENTRY_value(intname.s, i);
|
||||
for (j = 0; j < sk_X509_NAME_ENTRY_num(entries); j++) {
|
||||
entry = sk_X509_NAME_ENTRY_value(entries, j);
|
||||
entry->set = i;
|
||||
if (!sk_X509_NAME_ENTRY_push(nm.x->entries, entry))
|
||||
goto err;
|
||||
}
|
||||
sk_X509_NAME_ENTRY_free(entries);
|
||||
}
|
||||
sk_STACK_OF_X509_NAME_ENTRY_free(intname.s);
|
||||
ret = x509_name_canon(nm.x);
|
||||
if (!ret)
|
||||
goto err;
|
||||
nm.x->modified = 0;
|
||||
*val = nm.a;
|
||||
*in = p;
|
||||
return ret;
|
||||
err:
|
||||
if (nm.x != NULL)
|
||||
X509_NAME_free(nm.x);
|
||||
ASN1err(ASN1_F_X509_NAME_EX_D2I, ERR_R_NESTED_ASN1_ERROR);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out, const ASN1_ITEM *it, int tag, int aclass)
|
||||
static int x509_name_ex_i2d(ASN1_VALUE **val, unsigned char **out,
|
||||
const ASN1_ITEM *it, int tag, int aclass)
|
||||
{
|
||||
int ret;
|
||||
X509_NAME *a = (X509_NAME *)*val;
|
||||
if(a->modified) {
|
||||
ret = x509_name_encode(a);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
ret = x509_name_canon(a);
|
||||
if(ret < 0)
|
||||
return ret;
|
||||
}
|
||||
ret = a->bytes->length;
|
||||
if(out != NULL) {
|
||||
memcpy(*out,a->bytes->data,ret);
|
||||
*out+=ret;
|
||||
}
|
||||
return ret;
|
||||
int ret;
|
||||
X509_NAME *a = (X509_NAME *)*val;
|
||||
if (a->modified) {
|
||||
ret = x509_name_encode(a);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
ret = x509_name_canon(a);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
}
|
||||
ret = a->bytes->length;
|
||||
if (out != NULL) {
|
||||
memcpy(*out, a->bytes->data, ret);
|
||||
*out += ret;
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void local_sk_X509_NAME_ENTRY_free(STACK_OF(X509_NAME_ENTRY) *ne)
|
||||
{
|
||||
sk_X509_NAME_ENTRY_free(ne);
|
||||
}
|
||||
{
|
||||
sk_X509_NAME_ENTRY_free(ne);
|
||||
}
|
||||
|
||||
static void local_sk_X509_NAME_ENTRY_pop_free(STACK_OF(X509_NAME_ENTRY) *ne)
|
||||
{
|
||||
sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
|
||||
}
|
||||
{
|
||||
sk_X509_NAME_ENTRY_pop_free(ne, X509_NAME_ENTRY_free);
|
||||
}
|
||||
|
||||
static int x509_name_encode(X509_NAME *a)
|
||||
{
|
||||
union { STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
|
||||
ASN1_VALUE *a; } intname = {NULL};
|
||||
int len;
|
||||
unsigned char *p;
|
||||
STACK_OF(X509_NAME_ENTRY) *entries = NULL;
|
||||
X509_NAME_ENTRY *entry;
|
||||
int i, set = -1;
|
||||
intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
|
||||
if(!intname.s) goto memerr;
|
||||
for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
|
||||
entry = sk_X509_NAME_ENTRY_value(a->entries, i);
|
||||
if(entry->set != set) {
|
||||
entries = sk_X509_NAME_ENTRY_new_null();
|
||||
if(!entries) goto memerr;
|
||||
if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s,
|
||||
entries))
|
||||
goto memerr;
|
||||
set = entry->set;
|
||||
}
|
||||
if(!sk_X509_NAME_ENTRY_push(entries, entry)) goto memerr;
|
||||
}
|
||||
len = ASN1_item_ex_i2d(&intname.a, NULL,
|
||||
ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
|
||||
if (!BUF_MEM_grow(a->bytes,len)) goto memerr;
|
||||
p=(unsigned char *)a->bytes->data;
|
||||
ASN1_item_ex_i2d(&intname.a,
|
||||
&p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
|
||||
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
|
||||
local_sk_X509_NAME_ENTRY_free);
|
||||
a->modified = 0;
|
||||
return len;
|
||||
memerr:
|
||||
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
|
||||
local_sk_X509_NAME_ENTRY_free);
|
||||
ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
union {
|
||||
STACK_OF(STACK_OF_X509_NAME_ENTRY) *s;
|
||||
ASN1_VALUE *a;
|
||||
} intname = {
|
||||
NULL
|
||||
};
|
||||
int len;
|
||||
unsigned char *p;
|
||||
STACK_OF(X509_NAME_ENTRY) *entries = NULL;
|
||||
X509_NAME_ENTRY *entry;
|
||||
int i, set = -1;
|
||||
intname.s = sk_STACK_OF_X509_NAME_ENTRY_new_null();
|
||||
if (!intname.s)
|
||||
goto memerr;
|
||||
for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
|
||||
entry = sk_X509_NAME_ENTRY_value(a->entries, i);
|
||||
if (entry->set != set) {
|
||||
entries = sk_X509_NAME_ENTRY_new_null();
|
||||
if (!entries)
|
||||
goto memerr;
|
||||
if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname.s, entries))
|
||||
goto memerr;
|
||||
set = entry->set;
|
||||
}
|
||||
if (!sk_X509_NAME_ENTRY_push(entries, entry))
|
||||
goto memerr;
|
||||
}
|
||||
len = ASN1_item_ex_i2d(&intname.a, NULL,
|
||||
ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
|
||||
if (!BUF_MEM_grow(a->bytes, len))
|
||||
goto memerr;
|
||||
p = (unsigned char *)a->bytes->data;
|
||||
ASN1_item_ex_i2d(&intname.a,
|
||||
&p, ASN1_ITEM_rptr(X509_NAME_INTERNAL), -1, -1);
|
||||
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
|
||||
local_sk_X509_NAME_ENTRY_free);
|
||||
a->modified = 0;
|
||||
return len;
|
||||
memerr:
|
||||
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname.s,
|
||||
local_sk_X509_NAME_ENTRY_free);
|
||||
ASN1err(ASN1_F_X509_NAME_ENCODE, ERR_R_MALLOC_FAILURE);
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int x509_name_ex_print(BIO *out, ASN1_VALUE **pval,
|
||||
int indent,
|
||||
const char *fname,
|
||||
const ASN1_PCTX *pctx)
|
||||
{
|
||||
if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
|
||||
indent, pctx->nm_flags) <= 0)
|
||||
return 0;
|
||||
return 2;
|
||||
}
|
||||
int indent,
|
||||
const char *fname, const ASN1_PCTX *pctx)
|
||||
{
|
||||
if (X509_NAME_print_ex(out, (X509_NAME *)*pval,
|
||||
indent, pctx->nm_flags) <= 0)
|
||||
return 0;
|
||||
return 2;
|
||||
}
|
||||
|
||||
/* This function generates the canonical encoding of the Name structure.
|
||||
* In it all strings are converted to UTF8, leading, trailing and
|
||||
* multiple spaces collapsed, converted to lower case and the leading
|
||||
* SEQUENCE header removed.
|
||||
*
|
||||
* In future we could also normalize the UTF8 too.
|
||||
*
|
||||
* By doing this comparison of Name structures can be rapidly
|
||||
* perfomed by just using memcmp() of the canonical encoding.
|
||||
* By omitting the leading SEQUENCE name constraints of type
|
||||
* dirName can also be checked with a simple memcmp().
|
||||
/*
|
||||
* This function generates the canonical encoding of the Name structure. In
|
||||
* it all strings are converted to UTF8, leading, trailing and multiple
|
||||
* spaces collapsed, converted to lower case and the leading SEQUENCE header
|
||||
* removed. In future we could also normalize the UTF8 too. By doing this
|
||||
* comparison of Name structures can be rapidly perfomed by just using
|
||||
* memcmp() of the canonical encoding. By omitting the leading SEQUENCE name
|
||||
* constraints of type dirName can also be checked with a simple memcmp().
|
||||
*/
|
||||
|
||||
static int x509_name_canon(X509_NAME *a)
|
||||
{
|
||||
unsigned char *p;
|
||||
STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
|
||||
STACK_OF(X509_NAME_ENTRY) *entries = NULL;
|
||||
X509_NAME_ENTRY *entry, *tmpentry = NULL;
|
||||
int i, set = -1, ret = 0;
|
||||
{
|
||||
unsigned char *p;
|
||||
STACK_OF(STACK_OF_X509_NAME_ENTRY) *intname = NULL;
|
||||
STACK_OF(X509_NAME_ENTRY) *entries = NULL;
|
||||
X509_NAME_ENTRY *entry, *tmpentry = NULL;
|
||||
int i, set = -1, ret = 0;
|
||||
|
||||
if (a->canon_enc)
|
||||
{
|
||||
OPENSSL_free(a->canon_enc);
|
||||
a->canon_enc = NULL;
|
||||
}
|
||||
/* Special case: empty X509_NAME => null encoding */
|
||||
if (sk_X509_NAME_ENTRY_num(a->entries) == 0)
|
||||
{
|
||||
a->canon_enclen = 0;
|
||||
return 1;
|
||||
}
|
||||
intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
|
||||
if(!intname)
|
||||
goto err;
|
||||
for(i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++)
|
||||
{
|
||||
entry = sk_X509_NAME_ENTRY_value(a->entries, i);
|
||||
if(entry->set != set)
|
||||
{
|
||||
entries = sk_X509_NAME_ENTRY_new_null();
|
||||
if(!entries)
|
||||
goto err;
|
||||
if(!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
|
||||
goto err;
|
||||
set = entry->set;
|
||||
}
|
||||
tmpentry = X509_NAME_ENTRY_new();
|
||||
tmpentry->object = OBJ_dup(entry->object);
|
||||
if (!asn1_string_canon(tmpentry->value, entry->value))
|
||||
goto err;
|
||||
if(!sk_X509_NAME_ENTRY_push(entries, tmpentry))
|
||||
goto err;
|
||||
tmpentry = NULL;
|
||||
}
|
||||
if (a->canon_enc) {
|
||||
OPENSSL_free(a->canon_enc);
|
||||
a->canon_enc = NULL;
|
||||
}
|
||||
/* Special case: empty X509_NAME => null encoding */
|
||||
if (sk_X509_NAME_ENTRY_num(a->entries) == 0) {
|
||||
a->canon_enclen = 0;
|
||||
return 1;
|
||||
}
|
||||
intname = sk_STACK_OF_X509_NAME_ENTRY_new_null();
|
||||
if (!intname)
|
||||
goto err;
|
||||
for (i = 0; i < sk_X509_NAME_ENTRY_num(a->entries); i++) {
|
||||
entry = sk_X509_NAME_ENTRY_value(a->entries, i);
|
||||
if (entry->set != set) {
|
||||
entries = sk_X509_NAME_ENTRY_new_null();
|
||||
if (!entries)
|
||||
goto err;
|
||||
if (!sk_STACK_OF_X509_NAME_ENTRY_push(intname, entries))
|
||||
goto err;
|
||||
set = entry->set;
|
||||
}
|
||||
tmpentry = X509_NAME_ENTRY_new();
|
||||
if (!tmpentry)
|
||||
goto err;
|
||||
tmpentry->object = OBJ_dup(entry->object);
|
||||
if (!asn1_string_canon(tmpentry->value, entry->value))
|
||||
goto err;
|
||||
if (!sk_X509_NAME_ENTRY_push(entries, tmpentry))
|
||||
goto err;
|
||||
tmpentry = NULL;
|
||||
}
|
||||
|
||||
/* Finally generate encoding */
|
||||
/* Finally generate encoding */
|
||||
|
||||
a->canon_enclen = i2d_name_canon(intname, NULL);
|
||||
a->canon_enclen = i2d_name_canon(intname, NULL);
|
||||
|
||||
p = OPENSSL_malloc(a->canon_enclen);
|
||||
p = OPENSSL_malloc(a->canon_enclen);
|
||||
|
||||
if (!p)
|
||||
goto err;
|
||||
if (!p)
|
||||
goto err;
|
||||
|
||||
a->canon_enc = p;
|
||||
a->canon_enc = p;
|
||||
|
||||
i2d_name_canon(intname, &p);
|
||||
i2d_name_canon(intname, &p);
|
||||
|
||||
ret = 1;
|
||||
ret = 1;
|
||||
|
||||
err:
|
||||
err:
|
||||
|
||||
if (tmpentry)
|
||||
X509_NAME_ENTRY_free(tmpentry);
|
||||
if (intname)
|
||||
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
|
||||
local_sk_X509_NAME_ENTRY_pop_free);
|
||||
return ret;
|
||||
}
|
||||
if (tmpentry)
|
||||
X509_NAME_ENTRY_free(tmpentry);
|
||||
if (intname)
|
||||
sk_STACK_OF_X509_NAME_ENTRY_pop_free(intname,
|
||||
local_sk_X509_NAME_ENTRY_pop_free);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* Bitmap of all the types of string that will be canonicalized. */
|
||||
|
||||
#define ASN1_MASK_CANON \
|
||||
(B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
|
||||
| B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
|
||||
| B_ASN1_VISIBLESTRING)
|
||||
|
||||
#define ASN1_MASK_CANON \
|
||||
(B_ASN1_UTF8STRING | B_ASN1_BMPSTRING | B_ASN1_UNIVERSALSTRING \
|
||||
| B_ASN1_PRINTABLESTRING | B_ASN1_T61STRING | B_ASN1_IA5STRING \
|
||||
| B_ASN1_VISIBLESTRING)
|
||||
|
||||
static int asn1_string_canon(ASN1_STRING *out, ASN1_STRING *in)
|
||||
{
|
||||
unsigned char *to, *from;
|
||||
int len, i;
|
||||
{
|
||||
unsigned char *to, *from;
|
||||
int len, i;
|
||||
|
||||
/* If type not in bitmask just copy string across */
|
||||
if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON))
|
||||
{
|
||||
if (!ASN1_STRING_copy(out, in))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
/* If type not in bitmask just copy string across */
|
||||
if (!(ASN1_tag2bit(in->type) & ASN1_MASK_CANON)) {
|
||||
if (!ASN1_STRING_copy(out, in))
|
||||
return 0;
|
||||
return 1;
|
||||
}
|
||||
|
||||
out->type = V_ASN1_UTF8STRING;
|
||||
out->length = ASN1_STRING_to_UTF8(&out->data, in);
|
||||
if (out->length == -1)
|
||||
return 0;
|
||||
out->type = V_ASN1_UTF8STRING;
|
||||
out->length = ASN1_STRING_to_UTF8(&out->data, in);
|
||||
if (out->length == -1)
|
||||
return 0;
|
||||
|
||||
to = out->data;
|
||||
from = to;
|
||||
to = out->data;
|
||||
from = to;
|
||||
|
||||
len = out->length;
|
||||
len = out->length;
|
||||
|
||||
/* Convert string in place to canonical form.
|
||||
* Ultimately we may need to handle a wider range of characters
|
||||
* but for now ignore anything with MSB set and rely on the
|
||||
* isspace() and tolower() functions.
|
||||
*/
|
||||
/*
|
||||
* Convert string in place to canonical form. Ultimately we may need to
|
||||
* handle a wider range of characters but for now ignore anything with
|
||||
* MSB set and rely on the isspace() and tolower() functions.
|
||||
*/
|
||||
|
||||
/* Ignore leading spaces */
|
||||
while((len > 0) && !(*from & 0x80) && isspace(*from))
|
||||
{
|
||||
from++;
|
||||
len--;
|
||||
}
|
||||
/* Ignore leading spaces */
|
||||
while ((len > 0) && !(*from & 0x80) && isspace(*from)) {
|
||||
from++;
|
||||
len--;
|
||||
}
|
||||
|
||||
to = from + len - 1;
|
||||
to = from + len - 1;
|
||||
|
||||
/* Ignore trailing spaces */
|
||||
while ((len > 0) && !(*to & 0x80) && isspace(*to))
|
||||
{
|
||||
to--;
|
||||
len--;
|
||||
}
|
||||
/* Ignore trailing spaces */
|
||||
while ((len > 0) && !(*to & 0x80) && isspace(*to)) {
|
||||
to--;
|
||||
len--;
|
||||
}
|
||||
|
||||
to = out->data;
|
||||
to = out->data;
|
||||
|
||||
i = 0;
|
||||
while(i < len)
|
||||
{
|
||||
/* If MSB set just copy across */
|
||||
if (*from & 0x80)
|
||||
{
|
||||
*to++ = *from++;
|
||||
i++;
|
||||
}
|
||||
/* Collapse multiple spaces */
|
||||
else if (isspace(*from))
|
||||
{
|
||||
/* Copy one space across */
|
||||
*to++ = ' ';
|
||||
/* Ignore subsequent spaces. Note: don't need to
|
||||
* check len here because we know the last
|
||||
* character is a non-space so we can't overflow.
|
||||
*/
|
||||
do
|
||||
{
|
||||
from++;
|
||||
i++;
|
||||
}
|
||||
while(!(*from & 0x80) && isspace(*from));
|
||||
}
|
||||
else
|
||||
{
|
||||
*to++ = tolower(*from);
|
||||
from++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
i = 0;
|
||||
while (i < len) {
|
||||
/* If MSB set just copy across */
|
||||
if (*from & 0x80) {
|
||||
*to++ = *from++;
|
||||
i++;
|
||||
}
|
||||
/* Collapse multiple spaces */
|
||||
else if (isspace(*from)) {
|
||||
/* Copy one space across */
|
||||
*to++ = ' ';
|
||||
/*
|
||||
* Ignore subsequent spaces. Note: don't need to check len here
|
||||
* because we know the last character is a non-space so we can't
|
||||
* overflow.
|
||||
*/
|
||||
do {
|
||||
from++;
|
||||
i++;
|
||||
}
|
||||
while (!(*from & 0x80) && isspace(*from));
|
||||
} else {
|
||||
*to++ = tolower(*from);
|
||||
from++;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
out->length = to - out->data;
|
||||
out->length = to - out->data;
|
||||
|
||||
return 1;
|
||||
return 1;
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) *_intname,
|
||||
unsigned char **in)
|
||||
{
|
||||
int i, len, ltmp;
|
||||
ASN1_VALUE *v;
|
||||
STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
|
||||
static int i2d_name_canon(STACK_OF(STACK_OF_X509_NAME_ENTRY) * _intname,
|
||||
unsigned char **in)
|
||||
{
|
||||
int i, len, ltmp;
|
||||
ASN1_VALUE *v;
|
||||
STACK_OF(ASN1_VALUE) *intname = (STACK_OF(ASN1_VALUE) *)_intname;
|
||||
|
||||
len = 0;
|
||||
for (i = 0; i < sk_ASN1_VALUE_num(intname); i++)
|
||||
{
|
||||
v = sk_ASN1_VALUE_value(intname, i);
|
||||
ltmp = ASN1_item_ex_i2d(&v, in,
|
||||
ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
|
||||
if (ltmp < 0)
|
||||
return ltmp;
|
||||
len += ltmp;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
len = 0;
|
||||
for (i = 0; i < sk_ASN1_VALUE_num(intname); i++) {
|
||||
v = sk_ASN1_VALUE_value(intname, i);
|
||||
ltmp = ASN1_item_ex_i2d(&v, in,
|
||||
ASN1_ITEM_rptr(X509_NAME_ENTRIES), -1, -1);
|
||||
if (ltmp < 0)
|
||||
return ltmp;
|
||||
len += ltmp;
|
||||
}
|
||||
return len;
|
||||
}
|
||||
|
||||
int X509_NAME_set(X509_NAME **xn, X509_NAME *name)
|
||||
{
|
||||
X509_NAME *in;
|
||||
{
|
||||
X509_NAME *in;
|
||||
|
||||
if (!xn || !name) return(0);
|
||||
if (!xn || !name)
|
||||
return (0);
|
||||
|
||||
if (*xn != name) {
|
||||
in = X509_NAME_dup(name);
|
||||
if (in != NULL) {
|
||||
X509_NAME_free(*xn);
|
||||
*xn = in;
|
||||
}
|
||||
}
|
||||
return (*xn != NULL);
|
||||
}
|
||||
|
||||
if (*xn != name)
|
||||
{
|
||||
in=X509_NAME_dup(name);
|
||||
if (in != NULL)
|
||||
{
|
||||
X509_NAME_free(*xn);
|
||||
*xn=in;
|
||||
}
|
||||
}
|
||||
return(*xn != NULL);
|
||||
}
|
||||
|
||||
IMPLEMENT_STACK_OF(X509_NAME_ENTRY)
|
||||
|
||||
IMPLEMENT_ASN1_SET_OF(X509_NAME_ENTRY)
|
||||
|
||||
@ -1,6 +1,7 @@
|
||||
/* x_nx509.c */
|
||||
/* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL
|
||||
* project 2005.
|
||||
/*
|
||||
* Written by Dr Stephen N Henson (steve@openssl.org) for the OpenSSL project
|
||||
* 2005.
|
||||
*/
|
||||
/* ====================================================================
|
||||
* Copyright (c) 2005 The OpenSSL Project. All rights reserved.
|
||||
@ -10,7 +11,7 @@
|
||||
* are met:
|
||||
*
|
||||
* 1. Redistributions of source code must retain the above copyright
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
* notice, this list of conditions and the following disclaimer.
|
||||
*
|
||||
* 2. Redistributions in binary form must reproduce the above copyright
|
||||
* notice, this list of conditions and the following disclaimer in
|
||||
@ -64,9 +65,8 @@
|
||||
/* Old netscape certificate wrapper format */
|
||||
|
||||
ASN1_SEQUENCE(NETSCAPE_X509) = {
|
||||
ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING),
|
||||
ASN1_OPT(NETSCAPE_X509, cert, X509)
|
||||
ASN1_SIMPLE(NETSCAPE_X509, header, ASN1_OCTET_STRING),
|
||||
ASN1_OPT(NETSCAPE_X509, cert, X509)
|
||||
} ASN1_SEQUENCE_END(NETSCAPE_X509)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(NETSCAPE_X509)
|
||||
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -65,87 +65,89 @@
|
||||
|
||||
/* need to implement */
|
||||
int i2d_X509_PKEY(X509_PKEY *a, unsigned char **pp)
|
||||
{
|
||||
return(0);
|
||||
}
|
||||
{
|
||||
return (0);
|
||||
}
|
||||
|
||||
X509_PKEY *d2i_X509_PKEY(X509_PKEY **a, const unsigned char **pp, long length)
|
||||
{
|
||||
int i;
|
||||
M_ASN1_D2I_vars(a,X509_PKEY *,X509_PKEY_new);
|
||||
{
|
||||
int i;
|
||||
M_ASN1_D2I_vars(a, X509_PKEY *, X509_PKEY_new);
|
||||
|
||||
M_ASN1_D2I_Init();
|
||||
M_ASN1_D2I_start_sequence();
|
||||
M_ASN1_D2I_get_x(X509_ALGOR,ret->enc_algor,d2i_X509_ALGOR);
|
||||
M_ASN1_D2I_get_x(ASN1_OCTET_STRING,ret->enc_pkey,d2i_ASN1_OCTET_STRING);
|
||||
M_ASN1_D2I_Init();
|
||||
M_ASN1_D2I_start_sequence();
|
||||
M_ASN1_D2I_get_x(X509_ALGOR, ret->enc_algor, d2i_X509_ALGOR);
|
||||
M_ASN1_D2I_get_x(ASN1_OCTET_STRING, ret->enc_pkey, d2i_ASN1_OCTET_STRING);
|
||||
|
||||
ret->cipher.cipher=EVP_get_cipherbyname(
|
||||
OBJ_nid2ln(OBJ_obj2nid(ret->enc_algor->algorithm)));
|
||||
if (ret->cipher.cipher == NULL)
|
||||
{
|
||||
c.error=ASN1_R_UNSUPPORTED_CIPHER;
|
||||
c.line=__LINE__;
|
||||
goto err;
|
||||
}
|
||||
if (ret->enc_algor->parameter->type == V_ASN1_OCTET_STRING)
|
||||
{
|
||||
i=ret->enc_algor->parameter->value.octet_string->length;
|
||||
if (i > EVP_MAX_IV_LENGTH)
|
||||
{
|
||||
c.error=ASN1_R_IV_TOO_LARGE;
|
||||
c.line=__LINE__;
|
||||
goto err;
|
||||
}
|
||||
memcpy(ret->cipher.iv,
|
||||
ret->enc_algor->parameter->value.octet_string->data,i);
|
||||
}
|
||||
else
|
||||
memset(ret->cipher.iv,0,EVP_MAX_IV_LENGTH);
|
||||
M_ASN1_D2I_Finish(a,X509_PKEY_free,ASN1_F_D2I_X509_PKEY);
|
||||
}
|
||||
ret->cipher.cipher =
|
||||
EVP_get_cipherbyname(OBJ_nid2ln
|
||||
(OBJ_obj2nid(ret->enc_algor->algorithm)));
|
||||
if (ret->cipher.cipher == NULL) {
|
||||
c.error = ASN1_R_UNSUPPORTED_CIPHER;
|
||||
c.line = __LINE__;
|
||||
goto err;
|
||||
}
|
||||
if (ret->enc_algor->parameter->type == V_ASN1_OCTET_STRING) {
|
||||
i = ret->enc_algor->parameter->value.octet_string->length;
|
||||
if (i > EVP_MAX_IV_LENGTH) {
|
||||
c.error = ASN1_R_IV_TOO_LARGE;
|
||||
c.line = __LINE__;
|
||||
goto err;
|
||||
}
|
||||
memcpy(ret->cipher.iv,
|
||||
ret->enc_algor->parameter->value.octet_string->data, i);
|
||||
} else
|
||||
memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH);
|
||||
M_ASN1_D2I_Finish(a, X509_PKEY_free, ASN1_F_D2I_X509_PKEY);
|
||||
}
|
||||
|
||||
X509_PKEY *X509_PKEY_new(void)
|
||||
{
|
||||
X509_PKEY *ret=NULL;
|
||||
ASN1_CTX c;
|
||||
{
|
||||
X509_PKEY *ret = NULL;
|
||||
ASN1_CTX c;
|
||||
|
||||
M_ASN1_New_Malloc(ret,X509_PKEY);
|
||||
ret->version=0;
|
||||
M_ASN1_New(ret->enc_algor,X509_ALGOR_new);
|
||||
M_ASN1_New(ret->enc_pkey,M_ASN1_OCTET_STRING_new);
|
||||
ret->dec_pkey=NULL;
|
||||
ret->key_length=0;
|
||||
ret->key_data=NULL;
|
||||
ret->key_free=0;
|
||||
ret->cipher.cipher=NULL;
|
||||
memset(ret->cipher.iv,0,EVP_MAX_IV_LENGTH);
|
||||
ret->references=1;
|
||||
return(ret);
|
||||
M_ASN1_New_Error(ASN1_F_X509_PKEY_NEW);
|
||||
}
|
||||
M_ASN1_New_Malloc(ret, X509_PKEY);
|
||||
ret->version = 0;
|
||||
M_ASN1_New(ret->enc_algor, X509_ALGOR_new);
|
||||
M_ASN1_New(ret->enc_pkey, M_ASN1_OCTET_STRING_new);
|
||||
ret->dec_pkey = NULL;
|
||||
ret->key_length = 0;
|
||||
ret->key_data = NULL;
|
||||
ret->key_free = 0;
|
||||
ret->cipher.cipher = NULL;
|
||||
memset(ret->cipher.iv, 0, EVP_MAX_IV_LENGTH);
|
||||
ret->references = 1;
|
||||
return (ret);
|
||||
M_ASN1_New_Error(ASN1_F_X509_PKEY_NEW);
|
||||
}
|
||||
|
||||
void X509_PKEY_free(X509_PKEY *x)
|
||||
{
|
||||
int i;
|
||||
{
|
||||
int i;
|
||||
|
||||
if (x == NULL) return;
|
||||
if (x == NULL)
|
||||
return;
|
||||
|
||||
i=CRYPTO_add(&x->references,-1,CRYPTO_LOCK_X509_PKEY);
|
||||
i = CRYPTO_add(&x->references, -1, CRYPTO_LOCK_X509_PKEY);
|
||||
#ifdef REF_PRINT
|
||||
REF_PRINT("X509_PKEY",x);
|
||||
REF_PRINT("X509_PKEY", x);
|
||||
#endif
|
||||
if (i > 0) return;
|
||||
if (i > 0)
|
||||
return;
|
||||
#ifdef REF_CHECK
|
||||
if (i < 0)
|
||||
{
|
||||
fprintf(stderr,"X509_PKEY_free, bad reference count\n");
|
||||
abort();
|
||||
}
|
||||
if (i < 0) {
|
||||
fprintf(stderr, "X509_PKEY_free, bad reference count\n");
|
||||
abort();
|
||||
}
|
||||
#endif
|
||||
|
||||
if (x->enc_algor != NULL) X509_ALGOR_free(x->enc_algor);
|
||||
if (x->enc_pkey != NULL) M_ASN1_OCTET_STRING_free(x->enc_pkey);
|
||||
if (x->dec_pkey != NULL)EVP_PKEY_free(x->dec_pkey);
|
||||
if ((x->key_data != NULL) && (x->key_free)) OPENSSL_free(x->key_data);
|
||||
OPENSSL_free(x);
|
||||
}
|
||||
if (x->enc_algor != NULL)
|
||||
X509_ALGOR_free(x->enc_algor);
|
||||
if (x->enc_pkey != NULL)
|
||||
M_ASN1_OCTET_STRING_free(x->enc_pkey);
|
||||
if (x->dec_pkey != NULL)
|
||||
EVP_PKEY_free(x->dec_pkey);
|
||||
if ((x->key_data != NULL) && (x->key_free))
|
||||
OPENSSL_free(x->key_data);
|
||||
OPENSSL_free(x);
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,324 +62,313 @@
|
||||
#include <openssl/x509.h>
|
||||
#include "asn1_locl.h"
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
#include <openssl/rsa.h>
|
||||
# include <openssl/rsa.h>
|
||||
#endif
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
#include <openssl/dsa.h>
|
||||
# include <openssl/dsa.h>
|
||||
#endif
|
||||
|
||||
/* Minor tweak to operation: free up EVP_PKEY */
|
||||
static int pubkey_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
void *exarg)
|
||||
{
|
||||
if (operation == ASN1_OP_FREE_POST)
|
||||
{
|
||||
X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
|
||||
EVP_PKEY_free(pubkey->pkey);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
void *exarg)
|
||||
{
|
||||
if (operation == ASN1_OP_FREE_POST) {
|
||||
X509_PUBKEY *pubkey = (X509_PUBKEY *)*pval;
|
||||
EVP_PKEY_free(pubkey->pkey);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
ASN1_SEQUENCE_cb(X509_PUBKEY, pubkey_cb) = {
|
||||
ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
|
||||
ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
|
||||
ASN1_SIMPLE(X509_PUBKEY, algor, X509_ALGOR),
|
||||
ASN1_SIMPLE(X509_PUBKEY, public_key, ASN1_BIT_STRING)
|
||||
} ASN1_SEQUENCE_END_cb(X509_PUBKEY, X509_PUBKEY)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_PUBKEY)
|
||||
|
||||
int X509_PUBKEY_set(X509_PUBKEY **x, EVP_PKEY *pkey)
|
||||
{
|
||||
X509_PUBKEY *pk=NULL;
|
||||
{
|
||||
X509_PUBKEY *pk = NULL;
|
||||
|
||||
if (x == NULL) return(0);
|
||||
if (x == NULL)
|
||||
return (0);
|
||||
|
||||
if ((pk=X509_PUBKEY_new()) == NULL) goto error;
|
||||
if ((pk = X509_PUBKEY_new()) == NULL)
|
||||
goto error;
|
||||
|
||||
if (pkey->ameth)
|
||||
{
|
||||
if (pkey->ameth->pub_encode)
|
||||
{
|
||||
if (!pkey->ameth->pub_encode(pk, pkey))
|
||||
{
|
||||
X509err(X509_F_X509_PUBKEY_SET,
|
||||
X509_R_PUBLIC_KEY_ENCODE_ERROR);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
X509err(X509_F_X509_PUBKEY_SET,
|
||||
X509_R_METHOD_NOT_SUPPORTED);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
X509err(X509_F_X509_PUBKEY_SET,X509_R_UNSUPPORTED_ALGORITHM);
|
||||
goto error;
|
||||
}
|
||||
if (pkey->ameth) {
|
||||
if (pkey->ameth->pub_encode) {
|
||||
if (!pkey->ameth->pub_encode(pk, pkey)) {
|
||||
X509err(X509_F_X509_PUBKEY_SET,
|
||||
X509_R_PUBLIC_KEY_ENCODE_ERROR);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
X509err(X509_F_X509_PUBKEY_SET, X509_R_METHOD_NOT_SUPPORTED);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
X509err(X509_F_X509_PUBKEY_SET, X509_R_UNSUPPORTED_ALGORITHM);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (*x != NULL)
|
||||
X509_PUBKEY_free(*x);
|
||||
if (*x != NULL)
|
||||
X509_PUBKEY_free(*x);
|
||||
|
||||
*x=pk;
|
||||
*x = pk;
|
||||
|
||||
return 1;
|
||||
error:
|
||||
if (pk != NULL) X509_PUBKEY_free(pk);
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
error:
|
||||
if (pk != NULL)
|
||||
X509_PUBKEY_free(pk);
|
||||
return 0;
|
||||
}
|
||||
|
||||
EVP_PKEY *X509_PUBKEY_get(X509_PUBKEY *key)
|
||||
{
|
||||
EVP_PKEY *ret=NULL;
|
||||
{
|
||||
EVP_PKEY *ret = NULL;
|
||||
|
||||
if (key == NULL) goto error;
|
||||
if (key == NULL)
|
||||
goto error;
|
||||
|
||||
if (key->pkey != NULL)
|
||||
{
|
||||
CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
||||
return key->pkey;
|
||||
}
|
||||
if (key->pkey != NULL) {
|
||||
CRYPTO_add(&key->pkey->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
||||
return key->pkey;
|
||||
}
|
||||
|
||||
if (key->public_key == NULL) goto error;
|
||||
if (key->public_key == NULL)
|
||||
goto error;
|
||||
|
||||
if ((ret = EVP_PKEY_new()) == NULL)
|
||||
{
|
||||
X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
|
||||
goto error;
|
||||
}
|
||||
if ((ret = EVP_PKEY_new()) == NULL) {
|
||||
X509err(X509_F_X509_PUBKEY_GET, ERR_R_MALLOC_FAILURE);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm)))
|
||||
{
|
||||
X509err(X509_F_X509_PUBKEY_GET,X509_R_UNSUPPORTED_ALGORITHM);
|
||||
goto error;
|
||||
}
|
||||
if (!EVP_PKEY_set_type(ret, OBJ_obj2nid(key->algor->algorithm))) {
|
||||
X509err(X509_F_X509_PUBKEY_GET, X509_R_UNSUPPORTED_ALGORITHM);
|
||||
goto error;
|
||||
}
|
||||
|
||||
if (ret->ameth->pub_decode)
|
||||
{
|
||||
if (!ret->ameth->pub_decode(ret, key))
|
||||
{
|
||||
X509err(X509_F_X509_PUBKEY_GET,
|
||||
X509_R_PUBLIC_KEY_DECODE_ERROR);
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
|
||||
goto error;
|
||||
}
|
||||
if (ret->ameth->pub_decode) {
|
||||
if (!ret->ameth->pub_decode(ret, key)) {
|
||||
X509err(X509_F_X509_PUBKEY_GET, X509_R_PUBLIC_KEY_DECODE_ERROR);
|
||||
goto error;
|
||||
}
|
||||
} else {
|
||||
X509err(X509_F_X509_PUBKEY_GET, X509_R_METHOD_NOT_SUPPORTED);
|
||||
goto error;
|
||||
}
|
||||
|
||||
/* Check to see if another thread set key->pkey first */
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
|
||||
if (key->pkey)
|
||||
{
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
|
||||
EVP_PKEY_free(ret);
|
||||
ret = key->pkey;
|
||||
}
|
||||
else
|
||||
{
|
||||
key->pkey = ret;
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
|
||||
}
|
||||
CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
||||
/* Check to see if another thread set key->pkey first */
|
||||
CRYPTO_w_lock(CRYPTO_LOCK_EVP_PKEY);
|
||||
if (key->pkey) {
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
|
||||
EVP_PKEY_free(ret);
|
||||
ret = key->pkey;
|
||||
} else {
|
||||
key->pkey = ret;
|
||||
CRYPTO_w_unlock(CRYPTO_LOCK_EVP_PKEY);
|
||||
}
|
||||
CRYPTO_add(&ret->references, 1, CRYPTO_LOCK_EVP_PKEY);
|
||||
|
||||
return ret;
|
||||
return ret;
|
||||
|
||||
error:
|
||||
if (ret != NULL)
|
||||
EVP_PKEY_free(ret);
|
||||
return(NULL);
|
||||
}
|
||||
error:
|
||||
if (ret != NULL)
|
||||
EVP_PKEY_free(ret);
|
||||
return (NULL);
|
||||
}
|
||||
|
||||
/* Now two pseudo ASN1 routines that take an EVP_PKEY structure
|
||||
* and encode or decode as X509_PUBKEY
|
||||
/*
|
||||
* Now two pseudo ASN1 routines that take an EVP_PKEY structure and encode or
|
||||
* decode as X509_PUBKEY
|
||||
*/
|
||||
|
||||
EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp,
|
||||
long length)
|
||||
{
|
||||
X509_PUBKEY *xpk;
|
||||
EVP_PKEY *pktmp;
|
||||
xpk = d2i_X509_PUBKEY(NULL, pp, length);
|
||||
if(!xpk) return NULL;
|
||||
pktmp = X509_PUBKEY_get(xpk);
|
||||
X509_PUBKEY_free(xpk);
|
||||
if(!pktmp) return NULL;
|
||||
if(a)
|
||||
{
|
||||
EVP_PKEY_free(*a);
|
||||
*a = pktmp;
|
||||
}
|
||||
return pktmp;
|
||||
}
|
||||
EVP_PKEY *d2i_PUBKEY(EVP_PKEY **a, const unsigned char **pp, long length)
|
||||
{
|
||||
X509_PUBKEY *xpk;
|
||||
EVP_PKEY *pktmp;
|
||||
const unsigned char *q;
|
||||
q = *pp;
|
||||
xpk = d2i_X509_PUBKEY(NULL, &q, length);
|
||||
if (!xpk)
|
||||
return NULL;
|
||||
pktmp = X509_PUBKEY_get(xpk);
|
||||
X509_PUBKEY_free(xpk);
|
||||
if (!pktmp)
|
||||
return NULL;
|
||||
*pp = q;
|
||||
if (a) {
|
||||
EVP_PKEY_free(*a);
|
||||
*a = pktmp;
|
||||
}
|
||||
return pktmp;
|
||||
}
|
||||
|
||||
int i2d_PUBKEY(EVP_PKEY *a, unsigned char **pp)
|
||||
{
|
||||
X509_PUBKEY *xpk=NULL;
|
||||
int ret;
|
||||
if(!a) return 0;
|
||||
if(!X509_PUBKEY_set(&xpk, a)) return 0;
|
||||
ret = i2d_X509_PUBKEY(xpk, pp);
|
||||
X509_PUBKEY_free(xpk);
|
||||
return ret;
|
||||
}
|
||||
{
|
||||
X509_PUBKEY *xpk = NULL;
|
||||
int ret;
|
||||
if (!a)
|
||||
return 0;
|
||||
if (!X509_PUBKEY_set(&xpk, a))
|
||||
return 0;
|
||||
ret = i2d_X509_PUBKEY(xpk, pp);
|
||||
X509_PUBKEY_free(xpk);
|
||||
return ret;
|
||||
}
|
||||
|
||||
/* The following are equivalents but which return RSA and DSA
|
||||
* keys
|
||||
/*
|
||||
* The following are equivalents but which return RSA and DSA keys
|
||||
*/
|
||||
#ifndef OPENSSL_NO_RSA
|
||||
RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp,
|
||||
long length)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
RSA *key;
|
||||
const unsigned char *q;
|
||||
q = *pp;
|
||||
pkey = d2i_PUBKEY(NULL, &q, length);
|
||||
if (!pkey) return NULL;
|
||||
key = EVP_PKEY_get1_RSA(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (!key) return NULL;
|
||||
*pp = q;
|
||||
if (a)
|
||||
{
|
||||
RSA_free(*a);
|
||||
*a = key;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
RSA *d2i_RSA_PUBKEY(RSA **a, const unsigned char **pp, long length)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
RSA *key;
|
||||
const unsigned char *q;
|
||||
q = *pp;
|
||||
pkey = d2i_PUBKEY(NULL, &q, length);
|
||||
if (!pkey)
|
||||
return NULL;
|
||||
key = EVP_PKEY_get1_RSA(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (!key)
|
||||
return NULL;
|
||||
*pp = q;
|
||||
if (a) {
|
||||
RSA_free(*a);
|
||||
*a = key;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
int i2d_RSA_PUBKEY(RSA *a, unsigned char **pp)
|
||||
{
|
||||
EVP_PKEY *pktmp;
|
||||
int ret;
|
||||
if (!a) return 0;
|
||||
pktmp = EVP_PKEY_new();
|
||||
if (!pktmp)
|
||||
{
|
||||
ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
EVP_PKEY_set1_RSA(pktmp, a);
|
||||
ret = i2d_PUBKEY(pktmp, pp);
|
||||
EVP_PKEY_free(pktmp);
|
||||
return ret;
|
||||
}
|
||||
{
|
||||
EVP_PKEY *pktmp;
|
||||
int ret;
|
||||
if (!a)
|
||||
return 0;
|
||||
pktmp = EVP_PKEY_new();
|
||||
if (!pktmp) {
|
||||
ASN1err(ASN1_F_I2D_RSA_PUBKEY, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
EVP_PKEY_set1_RSA(pktmp, a);
|
||||
ret = i2d_PUBKEY(pktmp, pp);
|
||||
EVP_PKEY_free(pktmp);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_DSA
|
||||
DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp,
|
||||
long length)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
DSA *key;
|
||||
const unsigned char *q;
|
||||
q = *pp;
|
||||
pkey = d2i_PUBKEY(NULL, &q, length);
|
||||
if (!pkey) return NULL;
|
||||
key = EVP_PKEY_get1_DSA(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (!key) return NULL;
|
||||
*pp = q;
|
||||
if (a)
|
||||
{
|
||||
DSA_free(*a);
|
||||
*a = key;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
DSA *d2i_DSA_PUBKEY(DSA **a, const unsigned char **pp, long length)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
DSA *key;
|
||||
const unsigned char *q;
|
||||
q = *pp;
|
||||
pkey = d2i_PUBKEY(NULL, &q, length);
|
||||
if (!pkey)
|
||||
return NULL;
|
||||
key = EVP_PKEY_get1_DSA(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (!key)
|
||||
return NULL;
|
||||
*pp = q;
|
||||
if (a) {
|
||||
DSA_free(*a);
|
||||
*a = key;
|
||||
}
|
||||
return key;
|
||||
}
|
||||
|
||||
int i2d_DSA_PUBKEY(DSA *a, unsigned char **pp)
|
||||
{
|
||||
EVP_PKEY *pktmp;
|
||||
int ret;
|
||||
if(!a) return 0;
|
||||
pktmp = EVP_PKEY_new();
|
||||
if(!pktmp)
|
||||
{
|
||||
ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
EVP_PKEY_set1_DSA(pktmp, a);
|
||||
ret = i2d_PUBKEY(pktmp, pp);
|
||||
EVP_PKEY_free(pktmp);
|
||||
return ret;
|
||||
}
|
||||
{
|
||||
EVP_PKEY *pktmp;
|
||||
int ret;
|
||||
if (!a)
|
||||
return 0;
|
||||
pktmp = EVP_PKEY_new();
|
||||
if (!pktmp) {
|
||||
ASN1err(ASN1_F_I2D_DSA_PUBKEY, ERR_R_MALLOC_FAILURE);
|
||||
return 0;
|
||||
}
|
||||
EVP_PKEY_set1_DSA(pktmp, a);
|
||||
ret = i2d_PUBKEY(pktmp, pp);
|
||||
EVP_PKEY_free(pktmp);
|
||||
return ret;
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifndef OPENSSL_NO_EC
|
||||
EC_KEY *d2i_EC_PUBKEY(EC_KEY **a, const unsigned char **pp, long length)
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
EC_KEY *key;
|
||||
const unsigned char *q;
|
||||
q = *pp;
|
||||
pkey = d2i_PUBKEY(NULL, &q, length);
|
||||
if (!pkey) return(NULL);
|
||||
key = EVP_PKEY_get1_EC_KEY(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (!key) return(NULL);
|
||||
*pp = q;
|
||||
if (a)
|
||||
{
|
||||
EC_KEY_free(*a);
|
||||
*a = key;
|
||||
}
|
||||
return(key);
|
||||
}
|
||||
{
|
||||
EVP_PKEY *pkey;
|
||||
EC_KEY *key;
|
||||
const unsigned char *q;
|
||||
q = *pp;
|
||||
pkey = d2i_PUBKEY(NULL, &q, length);
|
||||
if (!pkey)
|
||||
return (NULL);
|
||||
key = EVP_PKEY_get1_EC_KEY(pkey);
|
||||
EVP_PKEY_free(pkey);
|
||||
if (!key)
|
||||
return (NULL);
|
||||
*pp = q;
|
||||
if (a) {
|
||||
EC_KEY_free(*a);
|
||||
*a = key;
|
||||
}
|
||||
return (key);
|
||||
}
|
||||
|
||||
int i2d_EC_PUBKEY(EC_KEY *a, unsigned char **pp)
|
||||
{
|
||||
EVP_PKEY *pktmp;
|
||||
int ret;
|
||||
if (!a) return(0);
|
||||
if ((pktmp = EVP_PKEY_new()) == NULL)
|
||||
{
|
||||
ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
|
||||
return(0);
|
||||
}
|
||||
EVP_PKEY_set1_EC_KEY(pktmp, a);
|
||||
ret = i2d_PUBKEY(pktmp, pp);
|
||||
EVP_PKEY_free(pktmp);
|
||||
return(ret);
|
||||
}
|
||||
{
|
||||
EVP_PKEY *pktmp;
|
||||
int ret;
|
||||
if (!a)
|
||||
return (0);
|
||||
if ((pktmp = EVP_PKEY_new()) == NULL) {
|
||||
ASN1err(ASN1_F_I2D_EC_PUBKEY, ERR_R_MALLOC_FAILURE);
|
||||
return (0);
|
||||
}
|
||||
EVP_PKEY_set1_EC_KEY(pktmp, a);
|
||||
ret = i2d_PUBKEY(pktmp, pp);
|
||||
EVP_PKEY_free(pktmp);
|
||||
return (ret);
|
||||
}
|
||||
#endif
|
||||
|
||||
int X509_PUBKEY_set0_param(X509_PUBKEY *pub, ASN1_OBJECT *aobj,
|
||||
int ptype, void *pval,
|
||||
unsigned char *penc, int penclen)
|
||||
{
|
||||
if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
|
||||
return 0;
|
||||
if (penc)
|
||||
{
|
||||
if (pub->public_key->data)
|
||||
OPENSSL_free(pub->public_key->data);
|
||||
pub->public_key->data = penc;
|
||||
pub->public_key->length = penclen;
|
||||
/* Set number of unused bits to zero */
|
||||
pub->public_key->flags&= ~(ASN1_STRING_FLAG_BITS_LEFT|0x07);
|
||||
pub->public_key->flags|=ASN1_STRING_FLAG_BITS_LEFT;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
int ptype, void *pval,
|
||||
unsigned char *penc, int penclen)
|
||||
{
|
||||
if (!X509_ALGOR_set0(pub->algor, aobj, ptype, pval))
|
||||
return 0;
|
||||
if (penc) {
|
||||
if (pub->public_key->data)
|
||||
OPENSSL_free(pub->public_key->data);
|
||||
pub->public_key->data = penc;
|
||||
pub->public_key->length = penclen;
|
||||
/* Set number of unused bits to zero */
|
||||
pub->public_key->flags &= ~(ASN1_STRING_FLAG_BITS_LEFT | 0x07);
|
||||
pub->public_key->flags |= ASN1_STRING_FLAG_BITS_LEFT;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int X509_PUBKEY_get0_param(ASN1_OBJECT **ppkalg,
|
||||
const unsigned char **pk, int *ppklen,
|
||||
X509_ALGOR **pa,
|
||||
X509_PUBKEY *pub)
|
||||
{
|
||||
if (ppkalg)
|
||||
*ppkalg = pub->algor->algorithm;
|
||||
if (pk)
|
||||
{
|
||||
*pk = pub->public_key->data;
|
||||
*ppklen = pub->public_key->length;
|
||||
}
|
||||
if (pa)
|
||||
*pa = pub->algor;
|
||||
return 1;
|
||||
}
|
||||
const unsigned char **pk, int *ppklen,
|
||||
X509_ALGOR **pa, X509_PUBKEY *pub)
|
||||
{
|
||||
if (ppkalg)
|
||||
*ppkalg = pub->algor->algorithm;
|
||||
if (pk) {
|
||||
*pk = pub->public_key->data;
|
||||
*ppklen = pub->public_key->length;
|
||||
}
|
||||
if (pa)
|
||||
*pa = pub->algor;
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -61,12 +61,13 @@
|
||||
#include <openssl/asn1t.h>
|
||||
#include <openssl/x509.h>
|
||||
|
||||
/* X509_REQ_INFO is handled in an unusual way to get round
|
||||
/*-
|
||||
* X509_REQ_INFO is handled in an unusual way to get round
|
||||
* invalid encodings. Some broken certificate requests don't
|
||||
* encode the attributes field if it is empty. This is in
|
||||
* violation of PKCS#10 but we need to tolerate it. We do
|
||||
* this by making the attributes field OPTIONAL then using
|
||||
* the callback to initialise it to an empty STACK.
|
||||
* the callback to initialise it to an empty STACK.
|
||||
*
|
||||
* This means that the field will be correctly encoded unless
|
||||
* we NULL out the field.
|
||||
@ -80,34 +81,36 @@
|
||||
*/
|
||||
|
||||
static int rinf_cb(int operation, ASN1_VALUE **pval, const ASN1_ITEM *it,
|
||||
void *exarg)
|
||||
void *exarg)
|
||||
{
|
||||
X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
|
||||
X509_REQ_INFO *rinf = (X509_REQ_INFO *)*pval;
|
||||
|
||||
if(operation == ASN1_OP_NEW_POST) {
|
||||
rinf->attributes = sk_X509_ATTRIBUTE_new_null();
|
||||
if(!rinf->attributes) return 0;
|
||||
}
|
||||
return 1;
|
||||
if (operation == ASN1_OP_NEW_POST) {
|
||||
rinf->attributes = sk_X509_ATTRIBUTE_new_null();
|
||||
if (!rinf->attributes)
|
||||
return 0;
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
ASN1_SEQUENCE_enc(X509_REQ_INFO, enc, rinf_cb) = {
|
||||
ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
|
||||
ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
|
||||
/* This isn't really OPTIONAL but it gets round invalid
|
||||
* encodings
|
||||
*/
|
||||
ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
|
||||
ASN1_SIMPLE(X509_REQ_INFO, version, ASN1_INTEGER),
|
||||
ASN1_SIMPLE(X509_REQ_INFO, subject, X509_NAME),
|
||||
ASN1_SIMPLE(X509_REQ_INFO, pubkey, X509_PUBKEY),
|
||||
/* This isn't really OPTIONAL but it gets round invalid
|
||||
* encodings
|
||||
*/
|
||||
ASN1_IMP_SET_OF_OPT(X509_REQ_INFO, attributes, X509_ATTRIBUTE, 0)
|
||||
} ASN1_SEQUENCE_END_enc(X509_REQ_INFO, X509_REQ_INFO)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_REQ_INFO)
|
||||
|
||||
ASN1_SEQUENCE_ref(X509_REQ, 0, CRYPTO_LOCK_X509_REQ) = {
|
||||
ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO),
|
||||
ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR),
|
||||
ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
|
||||
ASN1_SIMPLE(X509_REQ, req_info, X509_REQ_INFO),
|
||||
ASN1_SIMPLE(X509_REQ, sig_alg, X509_ALGOR),
|
||||
ASN1_SIMPLE(X509_REQ, signature, ASN1_BIT_STRING)
|
||||
} ASN1_SEQUENCE_END_ref(X509_REQ, X509_REQ)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_REQ)
|
||||
|
||||
IMPLEMENT_ASN1_DUP_FUNCTION(X509_REQ)
|
||||
|
||||
@ -5,21 +5,21 @@
|
||||
* This package is an SSL implementation written
|
||||
* by Eric Young (eay@cryptsoft.com).
|
||||
* The implementation was written so as to conform with Netscapes SSL.
|
||||
*
|
||||
*
|
||||
* This library is free for commercial and non-commercial use as long as
|
||||
* the following conditions are aheared to. The following conditions
|
||||
* apply to all code found in this distribution, be it the RC4, RSA,
|
||||
* lhash, DES, etc., code; not just the SSL code. The SSL documentation
|
||||
* included with this distribution is covered by the same copyright terms
|
||||
* except that the holder is Tim Hudson (tjh@cryptsoft.com).
|
||||
*
|
||||
*
|
||||
* Copyright remains Eric Young's, and as such any Copyright notices in
|
||||
* the code are not to be removed.
|
||||
* If this package is used in a product, Eric Young should be given attribution
|
||||
* as the author of the parts of the library used.
|
||||
* This can be in the form of a textual message at program startup or
|
||||
* in documentation (online or textual) provided with the package.
|
||||
*
|
||||
*
|
||||
* Redistribution and use in source and binary forms, with or without
|
||||
* modification, are permitted provided that the following conditions
|
||||
* are met:
|
||||
@ -34,10 +34,10 @@
|
||||
* Eric Young (eay@cryptsoft.com)"
|
||||
* The word 'cryptographic' can be left out if the rouines from the library
|
||||
* being used are not cryptographic related :-).
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* 4. If you include any Windows specific code (or a derivative thereof) from
|
||||
* the apps directory (application code) you must include an acknowledgement:
|
||||
* "This product includes software written by Tim Hudson (tjh@cryptsoft.com)"
|
||||
*
|
||||
*
|
||||
* THIS SOFTWARE IS PROVIDED BY ERIC YOUNG ``AS IS'' AND
|
||||
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
||||
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||
@ -49,7 +49,7 @@
|
||||
* 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.
|
||||
*
|
||||
*
|
||||
* The licence and distribution terms for any publically available version or
|
||||
* derivative of this code cannot be changed. i.e. this code cannot simply be
|
||||
* copied and put under another distribution licence
|
||||
@ -62,8 +62,8 @@
|
||||
#include <openssl/x509.h>
|
||||
|
||||
ASN1_SEQUENCE(X509_SIG) = {
|
||||
ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
|
||||
ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
|
||||
ASN1_SIMPLE(X509_SIG, algor, X509_ALGOR),
|
||||
ASN1_SIMPLE(X509_SIG, digest, ASN1_OCTET_STRING)
|
||||
} ASN1_SEQUENCE_END(X509_SIG)
|
||||
|
||||
IMPLEMENT_ASN1_FUNCTIONS(X509_SIG)
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user