1 /* $OpenBSD: keynote-sign.c,v 1.20 2021/10/24 21:24:20 deraadt Exp $ */ 2 /* 3 * The author of this code is Angelos D. Keromytis (angelos@dsl.cis.upenn.edu) 4 * 5 * This code was written by Angelos D. Keromytis in Philadelphia, PA, USA, 6 * in April-May 1998 7 * 8 * Copyright (C) 1998, 1999 by Angelos D. Keromytis. 9 * 10 * Permission to use, copy, and modify this software with or without fee 11 * is hereby granted, provided that this entire notice is included in 12 * all copies of any software which is or includes a copy or 13 * modification of this software. 14 * 15 * THIS SOFTWARE IS BEING PROVIDED "AS IS", WITHOUT ANY EXPRESS OR 16 * IMPLIED WARRANTY. IN PARTICULAR, THE AUTHORS MAKES NO 17 * REPRESENTATION OR WARRANTY OF ANY KIND CONCERNING THE 18 * MERCHANTABILITY OF THIS SOFTWARE OR ITS FITNESS FOR ANY PARTICULAR 19 * PURPOSE. 20 */ 21 22 #include <sys/types.h> 23 #include <sys/stat.h> 24 25 #include <ctype.h> 26 #include <regex.h> 27 #include <stdio.h> 28 #include <stdlib.h> 29 #include <string.h> 30 #include <fcntl.h> 31 #include <unistd.h> 32 33 #include "header.h" 34 #include "keynote.h" 35 36 void signusage(void); 37 38 void 39 signusage(void) 40 { 41 fprintf(stderr, "Arguments:\n"); 42 fprintf(stderr, "\t[-v] <AlgorithmName> <AssertionFile> " 43 "<PrivateKeyFile> [<print-offset>] [<print-length>]\n"); 44 } 45 46 void 47 keynote_sign(int argc, char *argv[]) 48 { 49 int begin = SIG_PRINT_OFFSET, prlen = SIG_PRINT_LENGTH; 50 char *buf, *buf2, *sig, *algname; 51 int fd, flg = 0, buflen; 52 struct stat sb; 53 54 if ((argc != 4) && 55 (argc != 5) && 56 (argc != 6) && 57 (argc != 7)) 58 { 59 signusage(); 60 exit(1); 61 } 62 63 if (!strcmp("-v", argv[1])) 64 flg = 1; 65 66 if (argc > 4 + flg) 67 { 68 begin = atoi(argv[4 + flg]); 69 if (begin <= -1) 70 { 71 fprintf(stderr, "Erroneous value for print-offset parameter.\n"); 72 exit(1); 73 } 74 } 75 76 if (argc > 5 + flg) 77 { 78 prlen = atoi(argv[5 + flg]); 79 if (prlen <= 0) 80 { 81 fprintf(stderr, "Erroneous value for print-length parameter.\n"); 82 exit(1); 83 } 84 } 85 86 /* Fix algorithm name */ 87 if (argv[1 + flg][strlen(argv[1 + flg]) - 1] != ':') 88 { 89 int len = strlen(argv[1 + flg]) + 2; 90 fprintf(stderr, "Algorithm name [%s] should be terminated with a " 91 "colon, fixing.\n", argv[1 + flg]); 92 algname = calloc(len, sizeof(char)); 93 if (algname == NULL) 94 { 95 perror("calloc()"); 96 exit(1); 97 } 98 99 strlcpy(algname, argv[1 + flg], len); 100 algname[strlen(algname)] = ':'; 101 } 102 else 103 algname = argv[1 + flg]; 104 105 /* Read assertion */ 106 fd = open(argv[2 + flg], O_RDONLY); 107 if (fd == -1) 108 { 109 perror(argv[2 + flg]); 110 exit(1); 111 } 112 113 if (fstat(fd, &sb) == -1) 114 { 115 perror("fstat()"); 116 exit(1); 117 } 118 119 if (sb.st_size == 0) /* Paranoid */ 120 { 121 fprintf(stderr, "Error: zero-sized assertion-file.\n"); 122 exit(1); 123 } 124 125 buflen = sb.st_size + 1; 126 buf = calloc(buflen, sizeof(char)); 127 if (buf == NULL) 128 { 129 perror("calloc()"); 130 exit(1); 131 } 132 133 if (read(fd, buf, buflen - 1) == -1) 134 { 135 perror("read()"); 136 exit(1); 137 } 138 139 close(fd); 140 141 /* Read private key file */ 142 fd = open(argv[3 + flg], O_RDONLY); 143 if (fd == -1) 144 { 145 perror(argv[3 + flg]); 146 exit(1); 147 } 148 149 if (fstat(fd, &sb) == -1) 150 { 151 perror("fstat()"); 152 exit(1); 153 } 154 155 if (sb.st_size == 0) /* Paranoid */ 156 { 157 fprintf(stderr, "Illegal key-file size 0\n"); 158 exit(1); 159 } 160 161 buf2 = calloc(sb.st_size + 1, sizeof(char)); 162 if (buf2 == NULL) 163 { 164 perror("calloc()"); 165 exit(1); 166 } 167 168 if (read(fd, buf2, sb.st_size) == -1) 169 { 170 perror("read()"); 171 exit(1); 172 } 173 174 close(fd); 175 176 sig = kn_sign_assertion(buf, buflen, buf2, algname, flg); 177 178 /* Free buffers */ 179 free(buf); 180 free(buf2); 181 182 if (sig == NULL) 183 { 184 switch (keynote_errno) 185 { 186 case ERROR_MEMORY: 187 fprintf(stderr, "Out of memory while creating signature.\n"); 188 break; 189 190 case ERROR_SYNTAX: 191 fprintf(stderr, "Bad assertion or algorithm format, or " 192 "unsupported algorithm while creating signature.\n"); 193 break; 194 195 default: 196 fprintf(stderr, "Unknown error while creating signature.\n"); 197 } 198 199 exit(1); 200 } 201 202 /* Print signature string */ 203 print_key(stdout, "", sig, begin, prlen); 204 205 free(sig); /* Just a reminder that the result is malloc'ed */ 206 207 exit(0); 208 } 209