📄 si_crpto.c
字号:
/*
* Copyright (C) Ericsson Mobile Communications AB, 2000.
* Licensed to AU-System AB.
* All rights reserved.
*
* This software is covered by the license agreement between
* the end user and AU-System AB, and may be used and copied
* only in accordance with the terms of the said agreement.
*
* Neither Ericsson Mobile Communications AB nor AU-System AB
* assumes any responsibility or liability for any errors or inaccuracies in
* this software, or any consequential, incidental or indirect damage arising
* out of the use of the Generic WAP Client software.
*/
/*
* si_crpto.c
*
* Created by Anders Edenbrandt, Mon Jan 10 10:27:04 2000.
*
* Revision history:
* 000119, AED: Moved parameter "options" from ST_encodeSignedContent
* to ST_createDigestInfo.
* Changed ST_encodeSignedContent to return a
* null-terminated byte string.
* 000809, AED: Removed the dependency on files from the WTLS
* implementation. Still needs the crypto API, though.
* 010119, AED: Use wapcvt instead of private conversion routines.
* Removed obsolete parameter from CRYPTa_hash.
* 010212, AED: Added conditional fix for the bug correction to the spec.
*
*/
#include "confvars.h"
#ifdef CAN_SIGN_TEXT
#include "cmmnrsrc.h"
#include "aapiclnt.h"
#include "aapicrpt.h"
#include "wapcvt.h"
#include "si_crpto.h"
/************************************************************
* Base-64 encoding
************************************************************/
/* The "alphabet" of base-64 encoding: */
static const BYTE b64[64] =
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
/*
* Given data of arbitrary length, create a base-64 encoding
* of said data, and place it in a newly allocated buffer.
* The created string will be null-terminated.
*
* NOTE: it is the caller's responsibility to deallocate
* the buffer holding the result.
*
* Returns 0 if OK, and -1 on error.
*/
static INT16
Base64Encoding (BYTE *inbuf, UINT16 inlen, BYTE **outbuf, UINT16 *outlen)
{
UINT16 len = (UINT16)(((inlen + 2) / 3) * 4);
BYTE *p;
UINT16 i, j;
/* Add space for line breaks. */
len += 2 * (len / 76);
*outbuf = NEWARRAY (BYTE, len + 1);
if (*outbuf == NULL) {
*outlen = 0;
return -1;
}
*outlen = len;
for (i = 0, j = 0, p = *outbuf; i + 2 < inlen; i += 3, p += 4, j += 4) {
if (j >= 76) {
p[0] = '\r';
p[1] = '\n';
p += 2;
j = 0;
}
p[0] = b64[(inbuf[i] >> 2) & 0x3f];
p[1] = b64[((inbuf[i] << 4) & 0x30) | ((inbuf[i + 1] >> 4) & 0x0f)];
p[2] = b64[((inbuf[i + 1] << 2) & 0x3c) | ((inbuf[i + 2] >> 6) & 0x03)];
p[3] = b64[inbuf[i + 2] & 0x3f];
}
if (i < inlen) {
if (j >= 76) {
p[0] = '\r';
p[1] = '\n';
p += 2;
}
p[0] = b64[(inbuf[i] >> 2) & 0x3f];
if (i + 1 < inlen) {
p[1] = b64[((inbuf[i] << 4) & 0x30) | ((inbuf[i + 1] >> 4) & 0x0f)];
p[2] = b64[((inbuf[i + 1] << 2) & 0x3c)];
}
else {
p[1] = b64[((inbuf[i] << 4) & 0x30)];
p[2] = '=';
}
p[3] = '=';
}
(*outbuf)[len] = '\0';
return 0;
}
/**********************************************************************
* Formatting of a Unix 32-bit time value (seconds since 1/1 1970)
* as a string in the format YYMMDDHHMMSS.
**********************************************************************/
static const BYTE m[12] = {
31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
static const BYTE m4[12] = {
31, 29, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31};
/*
* Format a Unix 32-bit time value (seconds since 1/1 1970)
* as a string in the format YYMMDDHHMMSS.
* Parameter "t" is the given time, "result" is where the result
* should be stored.
*/
static void
Time2String (UINT32 t, CHAR *result)
{
INT16 secs, mins, hours, days, months, years;
INT16 i, nly;
const BYTE *days_in_month;
/* First, divide into days, hours, minutes and seconds. */
days = (INT16)(t / 86400);
t = t % 86400;
hours = (INT16)(t / 3600);
t = t % 3600;
mins = (INT16)(t / 60);
secs = (INT16)(t % 60);
/* Now the number of days has to be divided into years and months.
* Start by approximating each year to be 365 days.
* This approximation will be at most one off.
* Compensate if necessary. */
years = (INT16)(days / 365);
days = (INT16)(days % 365);
/* In this interval (1970 - 2037), every fourth year is a leap year,
* without exceptions, starting with 1972. */
nly = (INT16)((years + 1) / 4);
if (days < nly) {
years--;
days = (INT16)(days + 365 - nly);
}
else {
days -= nly;
}
/* To determine the month we simply do a linear search through
* an array holding the number of days of each month.
* First we have to select the correct array though,
* there is one for leap years and one for non-leap years. */
if (((years + 2) % 4) == 0)
days_in_month = m4;
else
days_in_month = m;
for (i = 0; i < 12; i++) {
if (days < days_in_month[i])
break;
days -= days_in_month[i];
}
months = i;
/* We are done. The variable "years" holds the number of complete
* years that have passed since 1970; "months" holds the number
* of complete months that have passed since the beginning of
* the present year; and similarly for the other variables. */
sprintf (result, "%02d%02d%02d%02d%02d%02d\n",
(years + 1970) % 100, months + 1, days + 1, hours, mins, secs);
}
/************************************************************
* Routines to do encoding of a SignedContent structure.
************************************************************/
static INT16
wap_encode_signature (wap_cvt_t *obj, Signature *p)
{
if (!wap_cvt_uint8 (obj, &p->algorithm)) {
return FALSE;
}
if (p->algorithm != SIGALG_NULL) {
if (!wap_cvt_uint16 (obj, &p->siglen) ||
!wap_cvt_bytevector (obj, p->siglen, &p->sig)) {
return FALSE;
}
}
return TRUE;
}
static INT16
wap_encode_signer_info (wap_cvt_t *obj, SignerInfo *p)
{
if (!wap_cvt_uint8 (obj, &p->signerInfoType)) {
return FALSE;
}
switch (p->signerInfoType) {
case SIGNERINFO_IMPLICIT:
break;
case SIGNERINFO_SHA_KEY_HASH:
if (!wap_cvt_bytevector (obj, 20, &p->info)) {
return FALSE;
}
break;
case SIGNERINFO_WTLS_CERTIFICATE:
if (!wap_cvt_bytevector (obj, p->infoLen, &p->info)) {
return FALSE;
}
break;
case SIGNERINFO_X509_CERTIFICATE:
case SIGNERINFO_X968_CERTIFICATE:
if (!wap_cvt_uint16 (obj, &p->infoLen) ||
!wap_cvt_bytevector (obj, p->infoLen, &p->info)) {
return FALSE;
}
break;
case SIGNERINFO_CERTIFICATE_URL:
{
UINT8 tmp = (UINT8)p->infoLen;
if (!wap_cvt_uint8 (obj, &tmp) ||
!wap_cvt_bytevector (obj, tmp, &p->info))
return FALSE;
}
break;
default:
return FALSE;
}
return TRUE;
}
static INT16
wap_encode_signer_infos (wap_cvt_t *obj, SignerInfo *p)
{
wap_cvt_t tmp_cvt = *obj;
UINT16 len;
obj->pos += 2;
if (p[0].signerInfoType != SIGNERINFO_IMPLICIT) {
if (!wap_encode_signer_info (obj, &p[0])) {
return FALSE;
}
}
if (p[1].signerInfoType != SIGNERINFO_IMPLICIT) {
if (!wap_encode_signer_info (obj, &p[1])) {
return FALSE;
}
}
len = (UINT16)(obj->pos - tmp_cvt.pos - 2);
if (!wap_cvt_uint16 (&tmp_cvt, &len))
return FALSE;
return TRUE;
}
static INT16
wap_encode_content_info (wap_cvt_t *obj, ContentInfo *p)
{
if (!wap_cvt_uint8 (obj, &p->contentType) ||
!wap_cvt_uint16 (obj, &p->contentEncoding) ||
!wap_cvt_uint8 (obj, &p->contentPresent)) {
return FALSE;
}
if (p->contentPresent) {
if (!wap_cvt_uint16 (obj, &p->contentLen) ||
!wap_cvt_bytevector (obj, p->contentLen, &p->content)) {
return FALSE;
}
}
return TRUE;
}
static INT16
wap_encode_authenticated_attribute (wap_cvt_t *obj, AuthenticatedAttribute *p)
{
UINT8 tmp;
switch (p->attributeType) {
case ATTRIBUTETYPE_GMT_UTC_TIME:
tmp = 13;
if (!wap_cvt_uint8 (obj, &tmp) ||
!wap_cvt_uint8 (obj, &p->attributeType) ||
!wap_cvt_static_bytevector (obj, 12, p->_u.gmtUTCTime)) {
return FALSE;
}
break;
case ATTRIBUTETYPE_SIGNER_NONCE:
tmp = 9;
if (!wap_cvt_uint8 (obj, &tmp) ||
!wap_cvt_uint8 (obj, &p->attributeType) ||
!wap_cvt_static_bytevector (obj, 8, p->_u.signerNonce)) {
return FALSE;
}
break;
default:
return FALSE;
}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -