Add. Functions for reading PEM files and decoding ASN.1.
Этот коммит содержится в:
родитель
2afd706ca1
Коммит
be984707e2
221
src/pem.c
Обычный файл
221
src/pem.c
Обычный файл
@ -0,0 +1,221 @@
|
|||||||
|
/* Copyright (C) 2007 The Written Word, Inc. All rights reserved.
|
||||||
|
* Author: Simon Josefsson
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms,
|
||||||
|
* with or without modification, are permitted provided
|
||||||
|
* that the following conditions are met:
|
||||||
|
*
|
||||||
|
* Redistributions of source code must retain the above
|
||||||
|
* copyright notice, this list of conditions and the
|
||||||
|
* following disclaimer.
|
||||||
|
*
|
||||||
|
* Redistributions in binary form must reproduce the above
|
||||||
|
* copyright notice, this list of conditions and the following
|
||||||
|
* disclaimer in the documentation and/or other materials
|
||||||
|
* provided with the distribution.
|
||||||
|
*
|
||||||
|
* Neither the name of the copyright holder nor the names
|
||||||
|
* of any other contributors may be used to endorse or
|
||||||
|
* promote products derived from this software without
|
||||||
|
* specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
|
||||||
|
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
|
||||||
|
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
|
||||||
|
* OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
||||||
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR
|
||||||
|
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
|
||||||
|
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
|
||||||
|
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
||||||
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
|
||||||
|
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
|
||||||
|
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
|
||||||
|
* USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY
|
||||||
|
* OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "libssh2_priv.h"
|
||||||
|
|
||||||
|
static int readline (char *line, int line_size, FILE *fp)
|
||||||
|
{
|
||||||
|
if (!fgets(line, line_size, fp))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (*line && line[strlen(line) - 1] == '\r')
|
||||||
|
{
|
||||||
|
line[strlen(line) - 1] = '\0';
|
||||||
|
}
|
||||||
|
if (*line && line[strlen(line) - 1] == '\n')
|
||||||
|
{
|
||||||
|
line[strlen(line) - 1] = '\0';
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
#define LINE_SIZE 128
|
||||||
|
|
||||||
|
int _libssh2_pem_parse (LIBSSH2_SESSION *session,
|
||||||
|
const char *headerbegin,
|
||||||
|
const char *headerend,
|
||||||
|
FILE *fp,
|
||||||
|
char **data, unsigned int *datalen)
|
||||||
|
{
|
||||||
|
char line[LINE_SIZE];
|
||||||
|
int err;
|
||||||
|
char *b64data = NULL;
|
||||||
|
unsigned int b64datalen = 0;
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (readline(line, LINE_SIZE, fp))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
while (strcmp (line, headerbegin) != 0);
|
||||||
|
|
||||||
|
*line = '\0';
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
if (*line)
|
||||||
|
{
|
||||||
|
char *tmp;
|
||||||
|
size_t linelen;
|
||||||
|
|
||||||
|
linelen = strlen (line);
|
||||||
|
tmp = LIBSSH2_REALLOC (session, b64data,
|
||||||
|
b64datalen + linelen);
|
||||||
|
if (!tmp)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
memcpy (tmp + b64datalen, line, linelen);
|
||||||
|
b64data = tmp;
|
||||||
|
b64datalen += linelen;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (readline(line, LINE_SIZE, fp))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
} while (strcmp (line, headerend) != 0);
|
||||||
|
|
||||||
|
if (libssh2_base64_decode(session, data, datalen,
|
||||||
|
b64data, b64datalen))
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int read_asn1_length (const unsigned char *data,
|
||||||
|
unsigned int datalen,
|
||||||
|
unsigned int *len)
|
||||||
|
{
|
||||||
|
unsigned int lenlen;
|
||||||
|
int nextpos;
|
||||||
|
|
||||||
|
if (datalen < 1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
*len = data[0];
|
||||||
|
|
||||||
|
if (*len >= 0x80)
|
||||||
|
{
|
||||||
|
lenlen = *len & 0x7F;
|
||||||
|
*len = data[1];
|
||||||
|
if (1 + lenlen > datalen)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
if (lenlen > 1)
|
||||||
|
{
|
||||||
|
*len <<= 8;
|
||||||
|
*len |= data[2];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
lenlen = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
nextpos = 1 + lenlen;
|
||||||
|
if (lenlen > 2 || 1 + lenlen + *len > datalen)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return nextpos;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _libssh2_pem_decode_sequence (char **data, unsigned int *datalen)
|
||||||
|
{
|
||||||
|
unsigned int len;
|
||||||
|
unsigned int lenlen;
|
||||||
|
|
||||||
|
if (*datalen < 1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*data)[0] != '\x30')
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*data)++;
|
||||||
|
(*datalen)--;
|
||||||
|
|
||||||
|
lenlen = read_asn1_length (*data, *datalen, &len);
|
||||||
|
if (lenlen < 0 || lenlen + len != *datalen)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data += lenlen;
|
||||||
|
*datalen -= lenlen;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int _libssh2_pem_decode_integer (char **data, unsigned int *datalen,
|
||||||
|
char **i, unsigned int *ilen)
|
||||||
|
{
|
||||||
|
unsigned int len;
|
||||||
|
unsigned int lenlen;
|
||||||
|
|
||||||
|
if (*datalen < 1)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
if ((*data)[0] != '\x02')
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
(*data)++;
|
||||||
|
(*datalen)--;
|
||||||
|
|
||||||
|
lenlen = read_asn1_length (*data, *datalen, &len);
|
||||||
|
if (lenlen < 0 || lenlen + len > *datalen)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
*data += lenlen;
|
||||||
|
*datalen -= lenlen;
|
||||||
|
|
||||||
|
*i = *data;
|
||||||
|
*ilen = len;
|
||||||
|
|
||||||
|
*data += len;
|
||||||
|
*datalen -= len;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
Загрузка…
x
Ссылка в новой задаче
Block a user