pgpprsasc.c
来自「著名的加密软件的应用于电子邮件中」· C语言 代码 · 共 2,441 行 · 第 1/5 页
C
2,441 行
/* error in deamorline */
*error = sendAnnotate (ctx, myself,
PGPANN_ARMOR_BADLINE,
ctx->armorline, ctx->armorlen);
if (*error)
break;
ctx->state = 26;
goto case_26;
}
ctx->expectcrc = (i < 48);
ctx->crc = crcUpdate (ctx->crc, ctx->databuf, i);
ctx->datalen = i;
ctx->dataptr = ctx->databuf;
ctx->state++;
/* FALLTHROUGH */
case 20:
/* output the dearmored data, then goto state 17 */
part = ctx->part;
while (ctx->datalen) {
retval = writePartData (part, ctx->dataptr,
ctx->datalen, error);
ctx->dataptr += retval;
ctx->datalen -= retval;
if (*error)
return written;
}
ctx->state = 17;
goto case_17;
case 21:
case_21:
/* Deal with CRC */
crc = dearmorCrc (ctx);
if (crc < 0) {
/* error */
*error = sendAnnotate (ctx, myself,
PGPANN_ARMOR_CRCCANT,
ctx->armorline, ctx->armorlen);
if (*error)
break;
ctx->state = 26;
goto case_26;
}
if ((word32)crc != ctx->crc) {
/* mismatch */
*error = sendAnnotate (ctx, myself,
PGPANN_ARMOR_CRCBAD,
ctx->armorline, ctx->armorlen);
if (*error)
break;
ctx->state = 26;
goto case_26;
}
ctx->state++;
/* FALLTHROUGH */
case 22:
/* read until EOL to get to end of the last line */
ctx->armorptr = ctx->armorline;
ctx->armorlen = 0;
while (ctx->eol != 1) {
ctx->armorlen = 1; /* Preserve 1st char for doublespace logic */
retval = readLine (ctx, buf, size);
written += retval;
buf += retval;
size -= retval;
if (!size)
return written;
}
ctx->eol = 0;
ctx->eob = 0;
ctx->armorlen = 0;
ctx->state++;
/* FALLTHROUGH */
case 23:
/* call readline until we have EOB or EOL */
retval = readLine (ctx, buf, size);
size -= retval;
buf += retval;
written += retval;
if (ctx->eol || ctx->eob)
ctx->state++;
else
break;
/* FALLTHROUGH */
case 24:
case_24:
/* check for END */
if (ctx->armorlen < sizeof (prefix3) - 1 ||
memcmp (ctx->armorline, prefix3, sizeof (prefix3) - 1)) {
/* missing end -- do what??? */
;
}
#if MIMEPARSE
if (ctx->mime_signed) {
/* Special cleanup for MIME, wait for final boundary */
ctx->state = 80;
goto case_80;
}
#endif
ctx->state++;
/* FALLTHROUGH */
case 25:
/* read until EOL to get to end of the last line */
ctx->armorptr = ctx->armorline;
ctx->armorlen = 0;
while (ctx->eol != 1) {
ctx->armorlen = 1; /* Preserve 1st char for doublespace logic */
retval = readLine (ctx, buf, size);
written += retval;
buf += retval;
size -= retval;
if (!size)
return written;
}
ctx->state++;
/* FALLTHROUGH */
case 26:
case_26:
/*
* finish this part, send an end annotation if we need
* to, then clear the context and go to state 0
*/
if (ctx->annotation) {
pgpAssert (ctx->depth_at_ann == ctx->scope_depth);
*error = sendAnnotate (ctx, myself, ctx->annotation,
NULL, 0);
if (*error)
break;
ctx->annotation = 0;
}
ctx->state++;
/* FALLTHROUGH */
case 27:
part = ctx->part;
*error = donePart (ctx);
if (*error)
break;
ctx->part = NULL;
ctx->thispart = 0;
ctx->maxparts = 0;
memset (ctx->messageid, 0, sizeof (ctx->messageid));
ctx->dataptr = ctx->databuf;
ctx->datalen = 0;
ctx->armorptr = ctx->armorline;
ctx->armorlen = 0;
ctx->expectcrc = 0;
ctx->crlf = 0;
ctx->doublespace = 0;
ctx->firstheader = 0;
ctx->saved_crlf = 0;
ctx->hashlen = 0;
ctx->eol = 0;
ctx->eob = 0;
ctx->state = 0;
goto case_0;
/* BEGIN CLEARSIGNED MESSAGE BELOW HERE */
case 30:
case_30:
/* Send end-annotation (if we sent a begin annotation) */
if (ctx->annotation) {
pgpAssert (ctx->depth_at_ann == ctx->scope_depth);
*error = sendAnnotate (ctx, myself, ctx->annotation,
NULL, 0);
if (*error)
break;
ctx->annotation = 0;
}
ctx->state++;
/* FALLTHROUGH */
case 31:
/* Read until EOL == 1 to get to the end of the begin line */
pgpAssert (ctx->eol);
ctx->armorptr = ctx->armorline;
ctx->armorlen = 0;
while (ctx->eol != 1) {
ctx->armorlen = 0;
retval = readLine (ctx, buf, size);
written += retval;
buf += retval;
size -= retval;
if (!size)
return written;
}
ctx->eol = 0;
ctx->eob = 0;
ctx->armorlen = 0;
ctx->state++;
/* FALLTHROUGH */
case 32:
/* read the line after the begin: call readline until
* we have EOB or EOL */
retval = readLine (ctx, buf, size);
size -= retval;
buf += retval;
written += retval;
if (ctx->eol || ctx->eob)
ctx->state++;
else
break;
/* FALLTHROUGH */
case 33:
/* Make sure first line after "BEGIN" is empty or "Hash:" */
lineused = ctx->armorlen;
ptr = ctx->armorline;
/* Find trailing white space... */
while (lineused && isspace (ptr[lineused - 1]))
lineused--;
if (lineused && !ctx->hashlen) {
/* The line MUST be of the form:
* Hash: <ID>[, <ID>]*
*/
/* Check for "Hash:" here, put hashes into
* ctx->hashlist and number of hashes into
* ctx->hashlen
*/
if (memcmp (ctx->armorline, "Hash: ", 6)) {
/* Not a Hash -- Error out */
/* XXX: Should annotate here */
ctx->state = 3;
goto case_3;
}
lineused -= 6;
ptr += 6;
while (lineused) {
struct PgpHash const *h;
byte const *comma = (byte const *)
strchr ((char const *) ptr, ',');
unsigned len = comma ? comma-ptr : lineused;
h = pgpHashByName ((char const *)ptr, len);
if (!h) {
/* unknown hash.. now what? */
/*XXX: annotate?*/;
} else
ctx->hashlist[ctx->hashlen++] =
h->type;
ptr += len;
lineused -= len;
if (comma) {
if (memcmp (comma, ", ", 2)) {
/* invalid format */
/* XXX: annotate here */;
}
ptr += 2;
lineused -= 2;
}
} /* while */
if (!ctx->eol) {
/* Too long a line */
/* XXX: annotate: bad clearsig */
ctx->hashlen = 0;
ctx->state = 3;
goto case_3;
}
/* Now we need to get an *extra* line, the separator */
ctx->state = 30;
goto case_30;
} /* if (lineused && !ctx->hashlen) */
if (!ctx->eol || lineused) {
/*
* We either have a long line or non
* white-space. I bet someone's trying to
* trick us into believeing this is a real
* clearsigned message, but they've added some
* text to it. I dont buy it. Output as
* non-pgp text; goto state 3.
*/
/* XXX: Should send an annotation: bad clearsig */
ctx->hashlen = 0;
ctx->state = 3;
goto case_3;
}
ctx->state++;
/* FALLTHOUGH */
#if MIMEPARSE
case_34:
#endif
case 34:
/* Read until EOL == 1 to get to the next line */
pgpAssert (ctx->eol);
ctx->armorptr = ctx->armorline;
ctx->armorlen = 0;
while (ctx->eol != 1) {
ctx->armorlen = 0;
retval = readLine (ctx, buf, size);
written += retval;
buf += retval;
size -= retval;
if (!size)
return written;
}
ctx->eol = 0;
ctx->eob = 0;
ctx->armorlen = 0;
ctx->saved_crlf = 0;
ctx->crlf = 0;
ctx->state++;
/* FALLTHROUGH */
case 35:
/* Ok, this is a clearsigned message. Send a new
* begin annotation
*/
*error = sendAnnotate (ctx, myself, PGPANN_CLEARSIG_BEGIN,
NULL, 0);
if (*error)
break;
ctx->annotation = PGPANN_CLEARSIG_END;
ctx->depth_at_ann = ctx->scope_depth;
ctx->state++;
/* FALLTHROUGH */
case 36:
/* Get a new message part */
ctx->thispart = 1;
ctx->maxparts = 1;
msg = getMessage (ctx, NULL, 1);
if (!msg) {
/* This is an error */
*error = PGPERR_NOMEM;
break;
}
part = getPart (ctx, msg, ctx->thispart);
if (!part) {
/* This is an error too */
*error = PGPERR_NOMEM;
break;
}
/* And set it up as a clearsigned message */
*error = createClearsig (ctx, msg, part);
if (*error)
break;
ctx->part = part;
ctx->state = 39;
/* FALLTHROUGH */
/*
* Below starts the main processing loop for
* clearsigned messages. It reads in a line. If it
* is a BEGIN line it converts to the signature output
* and starts de-armoring the signature. Otherwise it
* will output any saved CRLF chars, then output this
* new line, saving (but not outputting) the CRLF
* chars at the end of the line. Then the loop
* continues.
*/
case_39:
case 39:
/* call readline until we have EOB or EOL */
retval = readLine (ctx, buf, size);
size -= retval;
buf += retval;
written += retval;
if (ctx->eol || ctx->eob)
ctx->state++;
else
break;
/* FALLTHROUGH */
case 40:
/*
* Check if this is a begin line. If so, start
* parsing the signature by jumping to case 9.
* Otherwise, if the line begins with '- ', move
* beyond that and fallthrough
*/
lineused = ctx->armorlen;
ptr = ctx->armorline;
while (lineused && isspace (ptr[lineused - 1]))
lineused--;
#if MIMEPARSE
if (ctx->mime_signed) {
if (lineused == ctx->mime_bound_len &&
!memcmp (ptr, ctx->mime_boundary, ctx->mime_bound_len)) {
/* Done with MIME body part, go look for sig */
ctx->state = 75;
goto case_75;
}
} else {
#endif
if (lineused == sizeof (sigprefix) - 1 &&
!memcmp (ptr, sigprefix, sizeof (sigprefix) - 1)) {
ctx->state = 9;
goto case_9;
}
if (!memcmp (ctx->armorline, "- ", 2)) {
ctx->armorptr = ctx->armorline + 2;
ctx->armorlen -= 2;
}
#if MIMEPARSE
}
#endif
ctx->state++;
/* FALLTHROUGH */
case 41:
/* output CRLF if we need to */
while (ctx->saved_crlf) {
if (ctx->saved_crlf & PGP_TEXTFILT_CR) {
i = writeExtraData (ctx, (byte const *)"\r",
1, error);
if (i)
ctx->saved_crlf &= ~PGP_TEXTFILT_CR;
if (*error)
break;
}
if (ctx->saved_crlf & PGP_TEXTFILT_LF) {
i = writeExtraData (ctx, (byte const *)"\n",
1, error);
if (i)
ctx->saved_crlf &= ~PGP_TEXTFILT_LF;
if (*error)
break;
}
}
ctx->state++;
/* FALLTHROUGH */
case 42:
case_42:
/*
* output armorline buffer; do not output crlf until
* the next line has been shown to not be the
* delimiter.
*/
ptr = ctx->armorptr + ctx->armorlen - 1;
while (*ptr == '\r' || *ptr == '\n') {
ptr--;
ctx->armorlen--;
}
while (ctx->armorlen) {
retval = writeExtraData (ctx, ctx->armorptr,
ctx->armorlen, error);
ctx->armorptr += retval;
ctx->armorlen -= retval;
if (*error)
return written;
}
ctx->armorptr = ctx->armorline;
ctx->state++;
/* FALLTHROUGH */
case 43:
/*
* if EOL == 1, clear state and goto state 39,
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?