📄 pgpkui.c
字号:
/*
* pgpkUI.c - Various user-interface helpers for working with key
* databases on a simple stdio tty interface.
*
* Copyright (C) 1997 Pretty Good Privacy, Inc. All rights reserved.
*
* Modified from pgpRingUI.c
*
* $Id: pgpkUI.c,v 1.1.2.6.2.3 1997/07/15 21:26:25 quark Exp $
*/
#if HAVE_CONFIG_H
#include "config.h"
#endif
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h> /* for strtol() */
#include <string.h> /* for strchr() */
#include <time.h> /* for time () */
#include "pgpDebug.h"
#include "pgpKeyDB.h"
#include "pgpOutput.h"
#include "pgpkUI.h"
#include "pgpErr.h"
#include "pgpTimeDate.h" /* for pgpDateString */
#include "pgpUserIO.h"
#include "pgpRngPub.h"
#include "pgpTrust.h"
#include "pgpTrstPkt.h"
#include "pgpTimeDate.h"
#include "pgpEnv.h"
#include "pgpMem.h"
/*
* The old PGP format...
Type Date keyID/bits User ID
PUB 1996-03-30 58B96505/2048 F0 4A 30 95 20 17 29 E0 DC A3 3F FB C6 5B 79 3F
foo
sig! 1996-03-30 58B96505 foo
PUB 1996-03-30 E9D1E021/4096 1A E2 EF AA FC CB 59 AC D4 2A 1A 90 E3 DD 4F 45
bar
sig! 1996-03-30 E9D1E021 bar
2 key(s) examined
*/
static char const hexchar[16] = {
'0','1','2','3','4','5','6','7',
'8','9','A','B','C','D','E','F'
};
/*
* Pretty-print a 128-bit key fingerprint into the supplied buffer,
* in varius forms, depending on the "len" argument:
* 1111111111222222222233333333334444444444555
* 01234567890123456789012345678901234567890123456789012
* 01 23 45 67 89 AB CD EF 01 23 45 67 89 AB CD EF/1024 (53 chars)
* 01 23 45 67 89 AB CD EF 01 23 45 67 89 AB CD EF/1024 (52 chars)
* 0123 4567 89AB CDEF 0123 4567 89AB CDEF/1024 (45 chars)
* 0123 4567 89AB CDEF 0123 4567 89AB CDEF/1024 (44 chars)
* 01234567 89ABCDEF 01234567 89ABCDEF/1024 (41 chars)
* 01234567 89ABCDEF 01234567 89ABCDEF/1024 (40 chars)
* 0123456789ABCDEF 0123456789ABCDEF/1024 (38 chars)
* 0123456789ABCDEF0123456789ABCDEF/1024 (37 chars)
* 0123456789ABCDEF0123456789ABCDE/1024
* 0123456789ABCDEF0123456789ABCD/1024
* 0123456789ABCDEF0123456789ABC/1024 (etc., truncating as needed)
* ...
* /1024
* /102
* /10
* /1
* /
*
* Returns the number of characters actually used, guaranteed to
* be <= the given len.
* Does NOT null-terminate the array.
*/
size_t
kdbTtyFormatFingerprint16(char *hash, char *buf, size_t len)
{
static signed char const limits[16] = {
-1, 46, 38, 46, 34, 46, 38, 46,
32, 46, 38, 46, 34, 46, 38, 46 };
char *p = buf;
int i;
for (i = 0; i < 16 && (size_t)(p-buf) != len; i++) {
/* Print each space iff it's okay to */
if (len > (unsigned)(int)limits[i])
*p++ = ' ';
/* Double space in the middle if appropriate */
if (i == 8 && len >= 36 && len != 39 && len != 47)
*p++ = ' ';
*p++ = hexchar[hash[i] >> 4 & 15];
if ((size_t)(p-buf) == len)
break;
*p++ = hexchar[hash[i] & 15];
}
return p-buf;
}
/*
* Pretty-print a 160-bit key fingerprint into the supplied buffer,
* in varius forms, depending on the "len" argument:
* Version a:
* 11111111112222222222333333333344444444
* 012345678901234567890123456789012345678901234567
* 01234 56789 ABCDE F0123 45678 9ABCD EF012 34567 (48 chars)
* 01234 56789 ABCDE F0123 45678 9ABCD EF012 34567 (47 chars)
* 0123456789 ABCDEF0123 456789ABCD EF01234567 (44 chars)
* 0123456789 ABCDEF0123 456789ABCD EF01234567 (43 chars)
* 0123456789ABCDEF0123 456789ABCDEF01234567 (41 chars)
* 0123456789ABCDEF0123456789ABCDEF01234567 (40 chars)
* 0123456789ABCDEF0123456789ABCDEF0123456
* 0123456789ABCDEF0123456789ABCDEF012345
* 0123456789ABCDEF0123456789ABCDEF01234 (etc., truncating as needed)
*
* Version b:
* 1111111111222222222233333333334444444444
* 01234567890123456789012345678901234567890123456789
* 0123 4567 89ab cdef 0123 4567 89ab cdef 0123 4567 (50 chars)
* 0123 4567 89ab cdef 0123 4567 89ab cdef 0123 4567 (49 chars)
* 01234567 89abcdef 01234567 89abcdef 01234567 (44 chars)
* 0123456789abcdef0123 456789abcdef01234567 (41 chars)
* 0123456789ABCDEF0123456789ABCDEF01234567 (40 chars)
* 0123456789ABCDEF0123456789ABCDEF0123456
* 0123456789ABCDEF0123456789ABCDEF012345
* 0123456789ABCDEF0123456789ABCDEF01234 (etc., truncating as needed)
*/
size_t
kdbTtyFormatFingerprint20(char *hash, char *buf, size_t len)
{
static signed char const limitsa[40] =
{-1, 46, 42, 46, 40, 46, 42, 46};
static signed char const limitsb[10] =
{-1, 48, 43, 48, 43, 48, 43, 48, 43, 48};
signed char const *limits = limitsb; /* Choose B */
int period = 4; /* Use 5 for A, 4 for B */
char *p = buf;
int i;
/* Unlike the 16 byte version, this loops per character */
for (i = 0; i < 40 && (size_t)(p-buf) != len; i++) {
/* Print each space iff it's okay to */
if (i%period == 0)
if (len > (unsigned)(int)limits[i/period])
*p++ = ' ';
/* Double space in the middle if appropriate */
if (i == 20 && len >= (unsigned)(limits==limitsa ? 44 : 50) &&
len != 47)
*p++ = ' ';
if (i & 1)
*p++ = hexchar[hash[i/2] & 15];
else
*p++ = hexchar[hash[i/2] >> 4 & 15];
}
return p-buf;
}
int
kdbTtyPutFingerprint16(Boolean DisplayHeaders,
PgpOutputType OutputType,
char *hash,
unsigned wid)
{
char buf[54]; /* Incestuous knowledge */
if (wid > sizeof(buf))
wid = sizeof(buf);
wid = (unsigned) kdbTtyFormatFingerprint16(hash, buf, (size_t) wid);
SpecifiedOutputBuffer(DisplayHeaders,
OutputType,
0,
buf,
sizeof(char),
wid);
return(wid);
}
int
kdbTtyPutFingerprint20(Boolean DisplayHeaders,
PgpOutputType OutputType,
char *hash, unsigned wid)
{
char buf[50]; /* Incestuous knowledge */
if (wid > sizeof(buf))
wid = sizeof(buf);
wid = (unsigned) kdbTtyFormatFingerprint20(hash, buf, (size_t) wid);
SpecifiedOutputBuffer(DisplayHeaders,
OutputType,
0,
buf,
sizeof(char),
wid);
return(wid);
}
int
kdbTtyPutKeyID(Boolean DisplayHeaders,
PgpOutputType OutputType,
char *buf)
{
int i;
if(DisplayHeaders)
SpecifiedOutputString(DisplayHeaders, OutputType, 0, "");
for (i = 4; i < 8; i++) {
SpecifiedOutputString(FALSE,
OutputType,
0,
"%c%c",
hexchar[buf[i] >> 4 & 15],
hexchar[buf[i] & 15]);
}
return 8;
}
int
kdbTtyPutSigID(Boolean DisplayHeaders,
PgpOutputType OutputType,
PGPCert *cert)
{
byte buf[8];
int i;
if(DisplayHeaders)
SpecifiedOutputString(TRUE, OutputType, 0, "");
i = sizeof (buf);
pgpGetCertString (cert,
kPGPCertPropKeyID,
(char *) buf,
(size_t *)&i);
for (i = 4; i < 8; i++) {
SpecifiedOutputString(FALSE,
OutputType,
0,
"%c%c",
hexchar[buf[i] >> 4 & 15],
hexchar[buf[i] & 15]);
}
return 8;
}
/*
* Write out the given string with all funny characters \-escaped in
* the manner of C strings, up to "maxlen" characters. Returns the
* actual number of characters printed, which will always be <= maxlen.
* If f is NULL, prints nothing. (May be useful for justification
* computations.) The string is surrounded by quotes q1 and q2
* (if not '\0'). q2 is also \-escaped if it appears in the string.
*/
unsigned
kdbTtyPutString(char const *str,
size_t len,
unsigned maxlen,
Boolean DisplayHeaders,
PgpOutputType OutputType,
char q1,
char q2)
{
int c = 0;
size_t t;
char const *p;
unsigned remaining = maxlen;
static char const escapes[] = "\a\b\f\n\r\t\v";
static char const letters[] = {'a','b','f','n','r','t','v'};
/* Opening quote */
if(remaining) {
if (q1) {
SpecifiedOutputString(DisplayHeaders, OutputType, 0, "%c", q1);
remaining--;
}
else {
if(DisplayHeaders)
/*Display the headers, if desired:*/
SpecifiedOutputString(TRUE, OutputType, 0, "");
}
}
for (;;) {
/* Printing can only expand the string, so truncate it */
if (len > remaining)
len = remaining;
/* Find a directly printable substring */
p = str; /* Remember start of substring */
while (len) {
c = (unsigned char)*str;
if (!isprint(c) || c == '\\' || c == q2)
break;
str++;
len--;
}
/* Print from p up to str */
t = (size_t)(str - p);
if (t) {
char *tmp;
if((tmp = pgpAlloc(sizeof(char) * (t + 1)))) {
memcpy(tmp, p, t);
*(tmp + t) = '\0';
SpecifiedOutputString(FALSE, OutputType, 0, tmp);
pgpFree(tmp);
}
remaining -= t;
}
/* Done with the string? */
if (!len)
break;
/* Note that remaining >= len > 0, so remaining > 0. */
/*
* c is a character to print that needs escaping.
* Now we're going to print it, so remove it from the string.
*/
len--;
str++;
/* Start with the obligatory backslash */
SpecifiedOutputString(FALSE, OutputType, 0, "\\");
if (!--remaining)
break;
/* Simple case 1: escaping printable characters */
if (isprint(c)) {
SpecifiedOutputString(FALSE, OutputType, 0, "%c", c);
--remaining;
continue;
}
/* Simple case 2: standard C escape */
p = strchr(escapes, c);
if (p && c) {
SpecifiedOutputString(FALSE,
OutputType,
0,
"%c",
letters[p - escapes]);
--remaining;
continue;
}
/* General octal escapes */
/* If next char makes it ambiguous, force 3-char escape */
if (len && isdigit(*str)) /* Force on 8 and 9, too! */
c += 256;
if (c > 077) {
SpecifiedOutputString(FALSE,
OutputType,
0,
"%c",
'0' + (c>>6 & 3));
if (!--remaining)
break;
}
if (c > 07) {
SpecifiedOutputString(FALSE,
OutputType,
0,
"%c",
'0' + (c>>3 & 7));
if (!--remaining)
break;
}
SpecifiedOutputString(FALSE, OutputType, 0, "%c", '0' + (c & 7));
--remaining;
}
/* Closing quote (if string ended) */
if (q2 && remaining) {
SpecifiedOutputString(FALSE, OutputType, 0, "%c", q2);
remaining--;
}
return maxlen - remaining;
}
/*
* Print info about a key, in the format
*
* 1024 bits, Key ID FBBB8AB1, created 1984-12-25
*
* The ", created" part is omitted if the creation timestamp is 0.
*/
void
kdbTtyPutKeyInfo(Boolean DisplayHeaders,
PgpOutputType OutputType,
PGPKey *key)
{
char buf[PGPDATESTRINGLEN+1];
PGPTime tstamp;
long keybits;
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -