Skip to content
Newer
Older
100644 173 lines (142 sloc) 4.52 KB
4c882be @bard Initial import.
bard authored
1 /*
2 * Copyright (C) 2007 by Massimiliano Mirra
3 *
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
8 *
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
13 *
14 * You should have received a copy of the GNU General Public License
15 * along with this program; if not, write to the Free Software
16 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
17 *
18 * Author: Massimiliano Mirra, <bard [at] hyperstruct [dot] net>
19 */
20
21
22 #include "pk11pub.h"
23 #include "nspr.h"
24 #include "nss.h"
25 #include "keyhi.h"
26 #include "plbase64.h"
27
28 #define MAXSIZE 32768
29
30
31 DERTemplate SECAlgorithmIDTemplate[] = {
32 { DER_SEQUENCE,
33 0, NULL, sizeof(SECAlgorithmID) },
34 { DER_OBJECT_ID,
35 offsetof(SECAlgorithmID,algorithm), },
36 { DER_OPTIONAL | DER_ANY,
37 offsetof(SECAlgorithmID,parameters), },
38 { 0, }
39 };
40
41 DERTemplate CERTSignatureDataTemplate[] =
42 {
43 { DER_SEQUENCE,
44 0, NULL, sizeof(CERTSignedData) },
45 { DER_INLINE,
46 offsetof(CERTSignedData,signatureAlgorithm),
47 SECAlgorithmIDTemplate, },
48 { DER_BIT_STRING,
49 offsetof(CERTSignedData,signature), },
50 { 0, }
51 };
52
53 int main(int argc, char *argv[])
54 {
55 PRBool readOnly = PR_FALSE;
56 PK11SlotInfo *slot = NULL;
57 SECOidTag alg = SEC_OID_PKCS1_SHA512_WITH_RSA_ENCRYPTION;
58 SECStatus rv;
59 char *progName;
60 SECKEYPrivateKey *key;
61 char data[MAXSIZE];
62 int dataLen;
63
64 progName = argv[0];
65 if(argc != 2) {
66 fprintf(stderr, "Usage: %s <mccoy profile dir>\n", progName);
67 goto shutdown;
68 }
69
70 char *configDirectory = argv[1];
71
72 // Initialize NSS
73
74 rv = NSS_Initialize(configDirectory, "", "", "secmod.db", 0);
75 if(rv != SECSuccess) {
76 SECU_PrintPRandOSError(progName);
77 rv = SECFailure;
78 goto shutdown;
79 }
80 SECU_RegisterDynamicOids();
81
82 // Exit if keys are protected.
83
84 slot = PK11_GetInternalKeySlot();
85 if(PK11_NeedUserInit(slot)) {
86 fprintf(stderr, "Error: needs user init.\n");
87 rv = SECFailure;
88 goto shutdown;
89 }
90
91 if(PK11_NeedLogin(slot)) {
92 fprintf(stderr, "Error: password-protected key databases not supported.\n");
93 rv = SECFailure;
94 goto shutdown;
95 }
96
97 // Retrieve first key in database
98
99 SECKEYPrivateKeyList *list;
100 SECKEYPrivateKeyListNode *node;
101 list = PK11_ListPrivKeysInSlot(slot, NULL, NULL);
102 if(!list) {
103 fprintf(stderr, "Error: no keys found.\n");
104 rv = SECFailure;
105 goto shutdown;
106 }
107 node = PRIVKEY_LIST_HEAD(list);
108 key = SECKEY_CopyPrivateKey(node->key);
109 SECKEY_DestroyPrivateKeyList(list);
110
111 // Read data
112
113 dataLen = fread(data, 1, MAXSIZE, stdin);
114
115 // Create signature
116
117 SECItem signature;
118 PORT_Memset(&signature, 0, sizeof(SECItem));
119
120 CERTSignedData sd;
121 PORT_Memset(&sd, 0, sizeof(CERTSignedData));
122
123 rv = SEC_SignData(&(sd.signature), data, dataLen, key, alg);
124 if(rv != SECSuccess) {
125 fprintf(stderr, "Error: could not sign data.\n");
126 goto shutdown;
127 }
128 sd.signature.len = sd.signature.len << 3;
129
130 PRArenaPool *arena;
131 arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
132 if(!arena) {
133 fprintf(stderr, "Error: couldn't get an arena (whatever that is).\n");
134 rv = SECFailure;
135 goto shutdown;
136 }
137
138 rv = SECOID_SetAlgorithmID(arena, &sd.signatureAlgorithm, alg, 0);
139 if(rv != SECSuccess) {
140 fprintf(stderr, "Error: couldn't set algorithm id.\n");
141 SECITEM_FreeItem(&(sd.signature), PR_FALSE);
142 PORT_FreeArena(arena, PR_FALSE);
143 goto shutdown;
144 }
145
146 // Encode results
147
148 SECItem result;
149 rv = DER_Encode(arena, &result, CERTSignatureDataTemplate, &sd);
150 SECITEM_FreeItem(&(sd.signature), PR_FALSE);
151 if(rv != SECSuccess) {
152 fprintf(stderr, "Error: couldn't encode result.\n");
153 PORT_FreeArena(arena, PR_FALSE);
154 goto shutdown;
155 }
156
157 char *sign = PL_Base64Encode((const char*)result.data, result.len, NULL);
158 PORT_FreeArena(arena, PR_FALSE);
159
160 printf("%s\n", sign);
161
162
163 shutdown:
164 if(slot) {
165 PK11_FreeSlot(slot);
166 }
167 if(rv == SECSuccess) {
168 return 0;
169 } else {
170 return 255;
171 }
172 }
Something went wrong with that request. Please try again.