Blame winpr/libwinpr/asn1/asn1.c

Packit 1fb8d4
/**
Packit 1fb8d4
 * WinPR: Windows Portable Runtime
Packit 1fb8d4
 * ASN.1 Encoding & Decoding Engine
Packit 1fb8d4
 *
Packit 1fb8d4
 * Copyright 2012 Marc-Andre Moreau <marcandre.moreau@gmail.com>
Packit 1fb8d4
 *
Packit 1fb8d4
 * Licensed under the Apache License, Version 2.0 (the "License");
Packit 1fb8d4
 * you may not use this file except in compliance with the License.
Packit 1fb8d4
 * You may obtain a copy of the License at
Packit 1fb8d4
 *
Packit 1fb8d4
 *     http://www.apache.org/licenses/LICENSE-2.0
Packit 1fb8d4
 *
Packit 1fb8d4
 * Unless required by applicable law or agreed to in writing, software
Packit 1fb8d4
 * distributed under the License is distributed on an "AS IS" BASIS,
Packit 1fb8d4
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
Packit 1fb8d4
 * See the License for the specific language governing permissions and
Packit 1fb8d4
 * limitations under the License.
Packit 1fb8d4
 */
Packit 1fb8d4
Packit 1fb8d4
#ifdef HAVE_CONFIG_H
Packit 1fb8d4
#include "config.h"
Packit 1fb8d4
#endif
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/asn1.h>
Packit 1fb8d4
Packit 1fb8d4
#include <winpr/crt.h>
Packit 1fb8d4
Packit 1fb8d4
#ifndef _WIN32
Packit 1fb8d4
Packit 1fb8d4
ASN1module_t ASN1_CreateModule(ASN1uint32_t nVersion, ASN1encodingrule_e eRule,
Packit Service 5a9772
                               ASN1uint32_t dwFlags, ASN1uint32_t cPDU,
Packit Service 5a9772
                               const ASN1GenericFun_t apfnEncoder[],
Packit Service 5a9772
                               const ASN1GenericFun_t apfnDecoder[],
Packit Service 5a9772
                               const ASN1FreeFun_t apfnFreeMemory[],
Packit Service 5a9772
                               const ASN1uint32_t acbStructSize[], ASN1magic_t nModuleName)
Packit 1fb8d4
{
Packit 1fb8d4
	ASN1module_t module = NULL;
Packit 1fb8d4
Packit 1fb8d4
	if (!((apfnEncoder) && (apfnDecoder) && (apfnFreeMemory) && (acbStructSize)))
Packit 1fb8d4
		return NULL;
Packit 1fb8d4
Packit Service 5a9772
	module = (ASN1module_t)calloc(1, sizeof(struct tagASN1module_t));
Packit 1fb8d4
Packit 1fb8d4
	if (module)
Packit 1fb8d4
	{
Packit 1fb8d4
		module->nModuleName = nModuleName;
Packit 1fb8d4
		module->dwFlags = dwFlags;
Packit 1fb8d4
		module->eRule = eRule;
Packit 1fb8d4
		module->cPDUs = cPDU;
Packit 1fb8d4
		module->apfnFreeMemory = apfnFreeMemory;
Packit 1fb8d4
		module->acbStructSize = acbStructSize;
Packit 1fb8d4
Packit 1fb8d4
		if (eRule & ASN1_BER_RULE)
Packit 1fb8d4
		{
Packit Service 5a9772
			module->BER.apfnEncoder = (const ASN1BerEncFun_t*)apfnEncoder;
Packit Service 5a9772
			module->BER.apfnDecoder = (const ASN1BerDecFun_t*)apfnDecoder;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return module;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void ASN1_CloseModule(ASN1module_t pModule)
Packit 1fb8d4
{
Packit 1fb8d4
	free(pModule);
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
ASN1error_e ASN1_CreateEncoder(ASN1module_t pModule, ASN1encoding_t* ppEncoderInfo,
Packit Service 5a9772
                               ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize, ASN1encoding_t pParent)
Packit 1fb8d4
{
Packit 1fb8d4
	ASN1error_e status;
Packit 1fb8d4
	ASN1encoding_t encoder;
Packit 1fb8d4
	ASN1encodingrule_e rule;
Packit 1fb8d4
Packit 1fb8d4
	if (pModule && ppEncoderInfo)
Packit 1fb8d4
	{
Packit 1fb8d4
		*ppEncoderInfo = 0;
Packit Service 5a9772
		encoder = (ASN1encoding_t)calloc(1, sizeof(struct ASN1encoding_s));
Packit 1fb8d4
Packit 1fb8d4
		if (encoder)
Packit 1fb8d4
		{
Packit 1fb8d4
			encoder->magic = 0x44434E45;
Packit 1fb8d4
			encoder->err = ASN1_SUCCESS;
Packit 1fb8d4
			encoder->dwFlags = pModule->dwFlags;
Packit 1fb8d4
			encoder->module = pModule;
Packit 1fb8d4
Packit 1fb8d4
			if (pbBuf && cbBufSize)
Packit 1fb8d4
			{
Packit 1fb8d4
				encoder->dwFlags |= ASN1ENCODE_SETBUFFER;
Packit 1fb8d4
				encoder->buf = pbBuf;
Packit 1fb8d4
				encoder->pos = pbBuf;
Packit 1fb8d4
				encoder->size = cbBufSize;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			if (pParent)
Packit 1fb8d4
			{
Packit Service 5a9772
				encoder[1].magic = (ASN1magic_t)pParent;
Packit 1fb8d4
				rule = pParent->eRule;
Packit 1fb8d4
			}
Packit 1fb8d4
			else
Packit 1fb8d4
			{
Packit Service 5a9772
				encoder[1].magic = (ASN1magic_t)encoder;
Packit 1fb8d4
				rule = pModule->eRule;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			encoder->eRule = rule;
Packit 1fb8d4
Packit 1fb8d4
			if (encoder->dwFlags & ASN1ENCODE_SETBUFFER)
Packit 1fb8d4
				goto LABEL_SET_BUFFER;
Packit 1fb8d4
Packit 1fb8d4
			if (!pParent)
Packit 1fb8d4
			{
Packit Service 5a9772
			LABEL_ENCODER_COMPLETE:
Packit 1fb8d4
				*ppEncoderInfo = encoder;
Packit 1fb8d4
				return ASN1_SUCCESS;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			if (rule & ASN1_BER_RULE)
Packit 1fb8d4
			{
Packit Service 5a9772
				// if (ASN1BEREncCheck(encoder, 1))
Packit 1fb8d4
				{
Packit 1fb8d4
					if (encoder->buf)
Packit 1fb8d4
						*encoder->buf = 0;
Packit Service 5a9772
				LABEL_SET_BUFFER:
Packit 1fb8d4
					if (pParent)
Packit Service 5a9772
						pParent[1].version = (ASN1uint32_t)encoder;
Packit 1fb8d4
Packit 1fb8d4
					goto LABEL_ENCODER_COMPLETE;
Packit 1fb8d4
				}
Packit 1fb8d4
Packit 1fb8d4
				status = ASN1_ERR_MEMORY;
Packit 1fb8d4
			}
Packit 1fb8d4
			else
Packit 1fb8d4
			{
Packit 1fb8d4
				status = ASN1_ERR_RULE;
Packit 1fb8d4
			}
Packit 1fb8d4
Packit 1fb8d4
			free(encoder);
Packit 1fb8d4
		}
Packit 1fb8d4
		else
Packit 1fb8d4
		{
Packit 1fb8d4
			status = ASN1_ERR_MEMORY;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		status = ASN1_ERR_BADARGS;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
ASN1error_e ASN1_Encode(ASN1encoding_t pEncoderInfo, void* pDataStruct, ASN1uint32_t nPduNum,
Packit Service 5a9772
                        ASN1uint32_t dwFlags, ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize)
Packit 1fb8d4
{
Packit 1fb8d4
	int flags;
Packit 1fb8d4
	ASN1error_e status;
Packit 1fb8d4
	ASN1module_t module;
Packit 1fb8d4
	ASN1BerEncFun_t pfnEncoder;
Packit 1fb8d4
Packit 1fb8d4
	if (!pEncoderInfo)
Packit 1fb8d4
		return ASN1_ERR_BADARGS;
Packit 1fb8d4
Packit 1fb8d4
	ASN1EncSetError(pEncoderInfo, ASN1_SUCCESS);
Packit 1fb8d4
Packit 1fb8d4
	if (dwFlags & 8)
Packit 1fb8d4
	{
Packit 1fb8d4
		pEncoderInfo->dwFlags |= 8;
Packit 1fb8d4
		pEncoderInfo->buf = pbBuf;
Packit 1fb8d4
		pEncoderInfo->pos = pbBuf;
Packit 1fb8d4
		pEncoderInfo->size = cbBufSize;
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		flags = dwFlags | pEncoderInfo->dwFlags;
Packit 1fb8d4
Packit 1fb8d4
		if (flags & 0x10)
Packit 1fb8d4
		{
Packit 1fb8d4
			pEncoderInfo->dwFlags &= 0xFFFFFFF7;
Packit 1fb8d4
			pEncoderInfo->buf = 0;
Packit 1fb8d4
			pEncoderInfo->pos = 0;
Packit 1fb8d4
			pEncoderInfo->size = 0;
Packit 1fb8d4
		}
Packit 1fb8d4
		else
Packit 1fb8d4
		{
Packit 1fb8d4
			if (!(dwFlags & ASN1ENCODE_REUSEBUFFER) && (flags & ASN1ENCODE_APPEND))
Packit 1fb8d4
				goto LABEL_MODULE;
Packit 1fb8d4
Packit 1fb8d4
			pEncoderInfo->pos = pEncoderInfo->buf;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	pEncoderInfo->len = 0;
Packit 1fb8d4
	pEncoderInfo->bit = 0;
Packit 1fb8d4
Packit 1fb8d4
LABEL_MODULE:
Packit 1fb8d4
	module = pEncoderInfo->module;
Packit 1fb8d4
Packit 1fb8d4
	if (nPduNum >= module->cPDUs)
Packit 1fb8d4
		goto LABEL_BAD_PDU;
Packit 1fb8d4
Packit 1fb8d4
	if (!(pEncoderInfo->eRule & ASN1_BER_RULE))
Packit 1fb8d4
	{
Packit 1fb8d4
		status = ASN1_ERR_RULE;
Packit 1fb8d4
		return ASN1EncSetError(pEncoderInfo, status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	pfnEncoder = module->BER.apfnEncoder[nPduNum];
Packit 1fb8d4
Packit 1fb8d4
	if (!pfnEncoder)
Packit 1fb8d4
	{
Packit Service 5a9772
	LABEL_BAD_PDU:
Packit 1fb8d4
		status = ASN1_ERR_BADPDU;
Packit 1fb8d4
		return ASN1EncSetError(pEncoderInfo, status);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (pfnEncoder(pEncoderInfo, 0, pDataStruct))
Packit 1fb8d4
	{
Packit Service 5a9772
		// ASN1BEREncFlush(pEncoderInfo);
Packit 1fb8d4
	}
Packit 1fb8d4
	else
Packit 1fb8d4
	{
Packit 1fb8d4
		if (pEncoderInfo[1].err >= 0)
Packit 1fb8d4
			ASN1EncSetError(pEncoderInfo, ASN1_ERR_CORRUPT);
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	if (pEncoderInfo[1].err < 0)
Packit 1fb8d4
	{
Packit 1fb8d4
		if (((dwFlags & 0xFF) | (pEncoderInfo->dwFlags & 0xFF)) & 0x10)
Packit 1fb8d4
		{
Packit 1fb8d4
			ASN1_FreeEncoded(pEncoderInfo, pEncoderInfo->buf);
Packit 1fb8d4
			pEncoderInfo->buf = 0;
Packit 1fb8d4
			pEncoderInfo->pos = 0;
Packit 1fb8d4
			pEncoderInfo->bit = 0;
Packit 1fb8d4
			pEncoderInfo->len = 0;
Packit 1fb8d4
			pEncoderInfo->size = 0;
Packit 1fb8d4
		}
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return pEncoderInfo[1].err;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void ASN1_CloseEncoder(ASN1encoding_t pEncoderInfo)
Packit 1fb8d4
{
Packit 1fb8d4
	ASN1magic_t magic;
Packit 1fb8d4
Packit 1fb8d4
	if (pEncoderInfo)
Packit 1fb8d4
	{
Packit 1fb8d4
		magic = pEncoderInfo[1].magic;
Packit 1fb8d4
Packit Service 5a9772
		if (pEncoderInfo != (ASN1encoding_t)magic)
Packit 1fb8d4
			pEncoderInfo[1].version = 0;
Packit 1fb8d4
Packit 1fb8d4
		free(pEncoderInfo);
Packit 1fb8d4
	}
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
ASN1error_e ASN1EncSetError(ASN1encoding_t enc, ASN1error_e err)
Packit 1fb8d4
{
Packit 1fb8d4
	ASN1error_e status;
Packit 1fb8d4
	ASN1encoding_t encoder;
Packit 1fb8d4
	ASN1encoding_t nextEncoder;
Packit 1fb8d4
Packit 1fb8d4
	status = err;
Packit 1fb8d4
	encoder = enc;
Packit 1fb8d4
Packit 1fb8d4
	while (encoder)
Packit 1fb8d4
	{
Packit Service 5a9772
		nextEncoder = (ASN1encoding_t)&encoder[1];
Packit 1fb8d4
Packit 1fb8d4
		encoder->err = err;
Packit 1fb8d4
Packit 1fb8d4
		if (encoder == nextEncoder)
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		encoder = nextEncoder;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
ASN1error_e ASN1DecSetError(ASN1decoding_t dec, ASN1error_e err)
Packit 1fb8d4
{
Packit 1fb8d4
	ASN1error_e status;
Packit 1fb8d4
	ASN1decoding_t decoder;
Packit 1fb8d4
	ASN1decoding_t nextDecoder;
Packit 1fb8d4
Packit 1fb8d4
	status = err;
Packit 1fb8d4
	decoder = dec;
Packit 1fb8d4
Packit 1fb8d4
	while (decoder)
Packit 1fb8d4
	{
Packit Service 5a9772
		nextDecoder = (ASN1decoding_t)&decoder[1];
Packit 1fb8d4
Packit 1fb8d4
		decoder->err = err;
Packit 1fb8d4
Packit 1fb8d4
		if (decoder == nextDecoder)
Packit 1fb8d4
			break;
Packit 1fb8d4
Packit 1fb8d4
		decoder = nextDecoder;
Packit 1fb8d4
	}
Packit 1fb8d4
Packit 1fb8d4
	return status;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void ASN1_FreeEncoded(ASN1encoding_t pEncoderInfo, void* pBuf)
Packit 1fb8d4
{
Packit 1fb8d4
	return;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
void ASN1_FreeDecoded(ASN1decoding_t pDecoderInfo, void* pDataStruct, ASN1uint32_t nPduNum)
Packit 1fb8d4
{
Packit 1fb8d4
	return;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
ASN1error_e ASN1_CreateDecoder(ASN1module_t pModule, ASN1decoding_t* ppDecoderInfo,
Packit Service 5a9772
                               ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize, ASN1decoding_t pParent)
Packit 1fb8d4
{
Packit Service 5a9772
	return ASN1_ERR_BADARGS;
Packit 1fb8d4
}
Packit 1fb8d4
Packit Service 5a9772
ASN1error_e ASN1_Decode(ASN1decoding_t pDecoderInfo, void** ppDataStruct, ASN1uint32_t nPduNum,
Packit Service 5a9772
                        ASN1uint32_t dwFlags, ASN1octet_t* pbBuf, ASN1uint32_t cbBufSize)
Packit 1fb8d4
{
Packit Service 5a9772
	return ASN1_ERR_BADARGS;
Packit 1fb8d4
}
Packit 1fb8d4
Packit 1fb8d4
#endif