mirror of
https://github.com/nmap/nmap.git
synced 2025-12-16 04:39:03 +00:00
Merged gsoc-ssh branch. Closes #910
This commit is contained in:
324
libssh2/src/pem.c
Normal file
324
libssh2/src/pem.c
Normal file
@@ -0,0 +1,324 @@
|
||||
/* Copyright (C) 2007 The Written Word, Inc.
|
||||
* Copyright (C) 2008, Simon Josefsson
|
||||
* All rights reserved.
|
||||
*
|
||||
* Redistribution and use in source and binary forms,
|
||||
* with or without modification, are permitted provided
|
||||
* that the following conditions are met:
|
||||
*
|
||||
* Redistributions of source code must retain the above
|
||||
* copyright notice, this list of conditions and the
|
||||
* following disclaimer.
|
||||
*
|
||||
* Redistributions in binary form must reproduce the above
|
||||
* copyright notice, this list of conditions and the following
|
||||
* disclaimer in the documentation and/or other materials
|
||||
* provided with the distribution.
|
||||
*
|
||||
* Neither the name of 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)
|
||||
{
|
||||
size_t len;
|
||||
|
||||
if (!line) {
|
||||
return -1;
|
||||
}
|
||||
if (!fgets(line, line_size, fp)) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (*line) {
|
||||
len = strlen(line);
|
||||
if (len > 0 && line[len - 1] == '\n') {
|
||||
line[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
if (*line) {
|
||||
len = strlen(line);
|
||||
if (len > 0 && line[len - 1] == '\r') {
|
||||
line[len - 1] = '\0';
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
readline_memory(char *line, size_t line_size,
|
||||
const char *filedata, size_t filedata_len,
|
||||
size_t *filedata_offset)
|
||||
{
|
||||
size_t off, len;
|
||||
|
||||
off = *filedata_offset;
|
||||
|
||||
for (len = 0; off + len < filedata_len && len < line_size; len++) {
|
||||
if (filedata[off + len] == '\n' ||
|
||||
filedata[off + len] == '\r') {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (len) {
|
||||
memcpy(line, filedata + off, len);
|
||||
*filedata_offset += len;
|
||||
}
|
||||
|
||||
line[len] = '\0';
|
||||
*filedata_offset += 1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#define LINE_SIZE 128
|
||||
|
||||
int
|
||||
_libssh2_pem_parse(LIBSSH2_SESSION * session,
|
||||
const char *headerbegin,
|
||||
const char *headerend,
|
||||
FILE * fp, unsigned char **data, unsigned int *datalen)
|
||||
{
|
||||
char line[LINE_SIZE];
|
||||
char *b64data = NULL;
|
||||
unsigned int b64datalen = 0;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
*line = '\0';
|
||||
|
||||
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) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
memcpy(tmp + b64datalen, line, linelen);
|
||||
b64data = tmp;
|
||||
b64datalen += linelen;
|
||||
}
|
||||
|
||||
*line = '\0';
|
||||
|
||||
if (readline(line, LINE_SIZE, fp)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
} while (strcmp(line, headerend) != 0);
|
||||
|
||||
if (!b64data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libssh2_base64_decode(session, (char**) data, datalen,
|
||||
b64data, b64datalen)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (b64data) {
|
||||
LIBSSH2_FREE(session, b64data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
_libssh2_pem_parse_memory(LIBSSH2_SESSION * session,
|
||||
const char *headerbegin,
|
||||
const char *headerend,
|
||||
const char *filedata, size_t filedata_len,
|
||||
unsigned char **data, unsigned int *datalen)
|
||||
{
|
||||
char line[LINE_SIZE];
|
||||
char *b64data = NULL;
|
||||
unsigned int b64datalen = 0;
|
||||
size_t off = 0;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
*line = '\0';
|
||||
|
||||
if (readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
|
||||
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) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
memcpy(tmp + b64datalen, line, linelen);
|
||||
b64data = tmp;
|
||||
b64datalen += linelen;
|
||||
}
|
||||
|
||||
*line = '\0';
|
||||
|
||||
if (readline_memory(line, LINE_SIZE, filedata, filedata_len, &off)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
} while (strcmp(line, headerend) != 0);
|
||||
|
||||
if (!b64data) {
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (libssh2_base64_decode(session, (char**) data, datalen,
|
||||
b64data, b64datalen)) {
|
||||
ret = -1;
|
||||
goto out;
|
||||
}
|
||||
|
||||
ret = 0;
|
||||
out:
|
||||
if (b64data) {
|
||||
LIBSSH2_FREE(session, b64data);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
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(unsigned char **data, unsigned int *datalen)
|
||||
{
|
||||
unsigned int len;
|
||||
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(unsigned char **data, unsigned int *datalen,
|
||||
unsigned char **i, unsigned int *ilen)
|
||||
{
|
||||
unsigned int len;
|
||||
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;
|
||||
}
|
||||
Reference in New Issue
Block a user