Changeset 95669 in vbox for trunk/src/VBox
- Timestamp:
- Jul 16, 2022 3:58:43 AM (2 years ago)
- Location:
- trunk/src/VBox/Runtime/tools
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
trunk/src/VBox/Runtime/tools/Makefile.kmk
r93115 r95669 77 77 bldRTSignTool_SOURCES = RTSignTool.cpp 78 78 bldRTSignTool_DEFS = IPRT_IN_BUILD_TOOL 79 bldRTSignTool_LIBS.win = Crypt32.lib NCrypt.lib 79 80 bldRTSignTool_POST_CMDS.win = $(VBOX_SIGN_IMAGE_CMDS) 80 81 if defined(VBOX_WITH_DARWIN_R0_DARWIN_IMAGE_VERIFICATION) && defined(VBOX_SIGNING_MODE) … … 214 215 RTSignTool_SOURCES = RTSignTool.cpp 215 216 RTSignTool_LIBS = $(PATH_STAGE_LIB)/SUPR3$(VBOX_SUFF_LIB) 217 RTSignTool_LIBS.win = Crypt32.lib NCrypt.lib 216 218 217 219 # RTTraceLogTool - Trace log collection and dissection tool. -
trunk/src/VBox/Runtime/tools/RTSignTool.cpp
r95659 r95669 46 46 #ifndef RT_OS_WINDOWS 47 47 # include <iprt/formats/pecoff.h> 48 #else 49 # include <iprt/utf16.h> 48 50 #endif 49 51 #include <iprt/crypto/applecodesign.h> … … 55 57 #include <iprt/crypto/spc.h> 56 58 #include <iprt/crypto/tsp.h> 59 #include <iprt/cpp/ministring.h> 57 60 #ifdef VBOX 58 61 # include <VBox/sup.h> /* Certificates */ … … 61 64 # include <iprt/win/windows.h> 62 65 # include <iprt/win/imagehlp.h> 66 # include <wincrypt.h> 67 # include <ncrypt.h> 63 68 #endif 64 69 … … 67 72 * Defined Constants And Macros * 68 73 *********************************************************************************************************************************/ 69 #define OPT_HASH_PAGES 1000 70 #define OPT_NO_HASH_PAGES 1001 71 #define OPT_CERT_FILE 1002 72 #define OPT_KEY_FILE 1003 73 #define OPT_ADD_CERT 1004 74 75 #define OPT_TIMESTAMP_CERT_FILE 1010 76 #define OPT_TIMESTAMP_KEY_FILE 1011 77 #define OPT_TIMESTAMP_TYPE 1012 78 #define OPT_TIMESTAMP_OVERRIDE 1016 74 #define OPT_OFF_CERT_FILE 0 /**< signtool /f file */ 75 #define OPT_OFF_CERT_SHA1 1 /**< signtool /sha1 thumbprint */ 76 #define OPT_OFF_CERT_SUBJECT 2 /**< signtool /n name */ 77 #define OPT_OFF_CERT_STORE 3 /**< signtool /s store */ 78 #define OPT_OFF_CERT_STORE_MACHINE 4 /**< signtool /sm */ 79 #define OPT_OFF_KEY_FILE 5 /**< no signtool equivalent, other than maybe /f. */ 80 #define OPT_OFF_KEY_PASSWORD 6 /**< signtool /p pass */ 81 #define OPT_OFF_KEY_PASSWORD_FILE 7 /**< no signtool equivalent. */ 82 #define OPT_OFF_KEY_NAME 8 /**< signtool /kc name */ 83 #define OPT_OFF_KEY_PROVIDER 9 /**< signtool /csp name (CSP = cryptographic service provider) */ 84 85 #define OPT_CERT_KEY_SWITCH_CASES(a_Instance, a_uBase, a_chOpt, a_ValueUnion, a_rcExit) \ 86 case (a_uBase) + OPT_OFF_CERT_FILE: \ 87 case (a_uBase) + OPT_OFF_CERT_SHA1: \ 88 case (a_uBase) + OPT_OFF_CERT_SUBJECT: \ 89 case (a_uBase) + OPT_OFF_CERT_STORE: \ 90 case (a_uBase) + OPT_OFF_CERT_STORE_MACHINE: \ 91 case (a_uBase) + OPT_OFF_KEY_FILE: \ 92 case (a_uBase) + OPT_OFF_KEY_PASSWORD: \ 93 case (a_uBase) + OPT_OFF_KEY_PASSWORD_FILE: \ 94 case (a_uBase) + OPT_OFF_KEY_NAME: \ 95 case (a_uBase) + OPT_OFF_KEY_PROVIDER: \ 96 a_rcExit = a_Instance.handleOption((a_chOpt) - (a_uBase), &(a_ValueUnion)); \ 97 break 98 99 #define OPT_CERT_KEY_GETOPTDEF_ENTRIES(a_szPrefix, a_uBase) \ 100 { a_szPrefix "cert-file", (a_uBase) + OPT_OFF_CERT_FILE, RTGETOPT_REQ_STRING }, \ 101 { a_szPrefix "cert-sha1", (a_uBase) + OPT_OFF_CERT_SHA1, RTGETOPT_REQ_STRING }, \ 102 { a_szPrefix "cert-subject", (a_uBase) + OPT_OFF_CERT_SUBJECT, RTGETOPT_REQ_STRING }, \ 103 { a_szPrefix "cert-store", (a_uBase) + OPT_OFF_CERT_STORE, RTGETOPT_REQ_STRING }, \ 104 { a_szPrefix "cert-machine-store", (a_uBase) + OPT_OFF_CERT_STORE_MACHINE, RTGETOPT_REQ_NOTHING }, \ 105 { a_szPrefix "key-file", (a_uBase) + OPT_OFF_KEY_FILE, RTGETOPT_REQ_STRING }, \ 106 { a_szPrefix "key-password", (a_uBase) + OPT_OFF_KEY_PASSWORD, RTGETOPT_REQ_STRING }, \ 107 { a_szPrefix "key-password-file", (a_uBase) + OPT_OFF_KEY_PASSWORD_FILE, RTGETOPT_REQ_STRING }, \ 108 { a_szPrefix "key-name", (a_uBase) + OPT_OFF_KEY_NAME, RTGETOPT_REQ_STRING }, \ 109 { a_szPrefix "key-provider", (a_uBase) + OPT_OFF_KEY_PROVIDER, RTGETOPT_REQ_STRING } 110 111 #define OPT_CERT_KEY_GETOPTDEF_COMPAT_ENTRIES(a_uBase) \ 112 { "/f", (a_uBase) + OPT_OFF_CERT_FILE, RTGETOPT_REQ_STRING }, \ 113 { "/sha1", (a_uBase) + OPT_OFF_CERT_SHA1, RTGETOPT_REQ_STRING }, \ 114 { "/n", (a_uBase) + OPT_OFF_CERT_SUBJECT, RTGETOPT_REQ_STRING }, \ 115 { "/s", (a_uBase) + OPT_OFF_CERT_STORE, RTGETOPT_REQ_STRING }, \ 116 { "/sm", (a_uBase) + OPT_OFF_CERT_STORE_MACHINE, RTGETOPT_REQ_NOTHING }, \ 117 { "/p", (a_uBase) + OPT_OFF_KEY_PASSWORD, RTGETOPT_REQ_STRING }, \ 118 { "/kc", (a_uBase) + OPT_OFF_KEY_NAME, RTGETOPT_REQ_STRING }, \ 119 { "/csp", (a_uBase) + OPT_OFF_KEY_PROVIDER, RTGETOPT_REQ_STRING } 120 121 #define OPT_CERT_KEY_SYNOPSIS(a_szPrefix) \ 122 "[" a_szPrefix "cert-file <file.pem|file.crt>] " \ 123 "[" a_szPrefix "cert-sha1 <fingerprint>] " \ 124 "[" a_szPrefix "cert-subject <part-name>] " \ 125 "[" a_szPrefix "cert-store <store>] " \ 126 "[" a_szPrefix "cert-machine-store] " \ 127 "[" a_szPrefix "key-file <file.pem|file.p12>] " \ 128 "[" a_szPrefix "key-password <password>] " \ 129 "[" a_szPrefix "key-password-file <file>|stdin] " \ 130 "[" a_szPrefix "key-name <name>] " \ 131 "[" a_szPrefix "key-provider <csp>] " 132 133 #define OPT_HASH_PAGES 1040 134 #define OPT_NO_HASH_PAGES 1041 135 #define OPT_ADD_CERT 1042 136 137 #define OPT_TIMESTAMP_TYPE 1043 138 #define OPT_TIMESTAMP_OVERRIDE 1044 79 139 80 140 … … 142 202 143 203 144 /**145 * Certificate w/ public key + private key pair for signing.146 */147 typedef struct SIGNTOOLKEYPAIR148 {149 RTCRX509CERTIFICATE Cert;150 PCRTCRX509CERTIFICATE pCertificate;151 RTCRKEY hPrivateKey;152 153 SIGNTOOLKEYPAIR()154 : pCertificate(NULL)155 , hPrivateKey(NIL_RTCRKEY)156 {157 RT_ZERO(Cert);158 }159 160 ~SIGNTOOLKEYPAIR()161 {162 if (hPrivateKey != NIL_RTCRKEY)163 {164 RTCrKeyRelease(hPrivateKey);165 hPrivateKey = NIL_RTCRKEY;166 }167 if (pCertificate == &Cert)168 {169 RTCrX509Certificate_Delete(&Cert);170 pCertificate = NULL;171 }172 }173 174 bool isComplete(void) const175 {176 return pCertificate && hPrivateKey != NIL_RTCRKEY;177 }178 179 bool isNull(void) const180 {181 return pCertificate == NULL && hPrivateKey == NIL_RTCRKEY;182 }183 } SIGNTOOLKEYPAIR;184 185 186 204 /********************************************************************************************************************************* 187 205 * Internal Functions * … … 193 211 static int HandleShowExeWorkerPkcs7Display(PSHOWEXEPKCS7 pThis, PRTCRPKCS7SIGNEDDATA pSignedData, size_t offPrefix, 194 212 PCRTCRPKCS7CONTENTINFO pContentInfo); 213 214 215 /********************************************************************************************************************************* 216 * Certificate and Private Key Handling (options, ++). * 217 *********************************************************************************************************************************/ 218 /** @todo create a better fake certificate. */ 219 const unsigned char g_abFakeCertificate[] = 220 { 221 0x30, 0x82, 0x03, 0xb2, 0x30, 0x82, 0x02, 0x9a, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x10, 0x31, /* 0x00000000: 0...0..........1 */ 222 0xba, 0xd6, 0xbc, 0x5d, 0x9a, 0xe0, 0xb0, 0x4e, 0xd4, 0xfa, 0xcc, 0xfb, 0x47, 0x00, 0x5c, 0x30, /* 0x00000010: ...]...N....G.\0 */ 223 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, 0x00, 0x30, 0x71, /* 0x00000020: ...*.H........0q */ 224 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x54, 0x69, 0x6d, 0x65, 0x73, /* 0x00000030: 1.0...U....Times */ 225 0x74, 0x61, 0x6d, 0x70, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, 0x32, 0x31, 0x0c, /* 0x00000040: tamp Signing 21. */ 226 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x03, 0x44, 0x65, 0x76, 0x31, 0x15, 0x30, 0x13, /* 0x00000050: 0...U....Dev1.0. */ 227 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, 0x6f, 0x6d, 0x70, /* 0x00000060: ..U....Test Comp */ 228 0x61, 0x6e, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, 0x09, 0x53, 0x74, /* 0x00000070: any1.0...U....St */ 229 0x75, 0x74, 0x74, 0x67, 0x61, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x08, /* 0x00000080: uttgart1.0...U.. */ 230 0x0c, 0x02, 0x42, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, 0x13, 0x02, 0x44, /* 0x00000090: ..BB1.0...U....D */ 231 0x45, 0x30, 0x1e, 0x17, 0x0d, 0x30, 0x30, 0x30, 0x31, 0x30, 0x31, 0x30, 0x30, 0x30, 0x31, 0x30, /* 0x000000a0: E0...00010100010 */ 232 0x31, 0x5a, 0x17, 0x0d, 0x33, 0x36, 0x31, 0x32, 0x33, 0x31, 0x32, 0x32, 0x35, 0x39, 0x35, 0x39, /* 0x000000b0: 1Z..361231225959 */ 233 0x5a, 0x30, 0x71, 0x31, 0x1c, 0x30, 0x1a, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x54, 0x69, /* 0x000000c0: Z0q1.0...U....Ti */ 234 0x6d, 0x65, 0x73, 0x74, 0x61, 0x6d, 0x70, 0x20, 0x53, 0x69, 0x67, 0x6e, 0x69, 0x6e, 0x67, 0x20, /* 0x000000d0: mestamp Signing */ 235 0x32, 0x31, 0x0c, 0x30, 0x0a, 0x06, 0x03, 0x55, 0x04, 0x0b, 0x0c, 0x03, 0x44, 0x65, 0x76, 0x31, /* 0x000000e0: 21.0...U....Dev1 */ 236 0x15, 0x30, 0x13, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x0c, 0x54, 0x65, 0x73, 0x74, 0x20, 0x43, /* 0x000000f0: .0...U....Test C */ 237 0x6f, 0x6d, 0x70, 0x61, 0x6e, 0x79, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x07, 0x0c, /* 0x00000100: ompany1.0...U... */ 238 0x09, 0x53, 0x74, 0x75, 0x74, 0x74, 0x67, 0x61, 0x72, 0x74, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, /* 0x00000110: .Stuttgart1.0... */ 239 0x55, 0x04, 0x08, 0x0c, 0x02, 0x42, 0x42, 0x31, 0x0b, 0x30, 0x09, 0x06, 0x03, 0x55, 0x04, 0x06, /* 0x00000120: U....BB1.0...U.. */ 240 0x13, 0x02, 0x44, 0x45, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, /* 0x00000130: ..DE0.."0...*.H. */ 241 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f, 0x00, 0x30, 0x82, 0x01, 0x0a, /* 0x00000140: ............0... */ 242 0x02, 0x82, 0x01, 0x01, 0x00, 0xdb, 0x18, 0x63, 0x33, 0xf2, 0x08, 0x90, 0x5a, 0xab, 0xda, 0x88, /* 0x00000150: .......c3...Z... */ 243 0x73, 0x86, 0x49, 0xea, 0x8b, 0xaf, 0xcf, 0x67, 0x15, 0xa5, 0x39, 0xe6, 0xa2, 0x94, 0x0c, 0x3f, /* 0x00000160: s.I....g..9....? */ 244 0xa1, 0x2e, 0x6c, 0xd2, 0xdf, 0x01, 0x65, 0x6d, 0xed, 0x6c, 0x4c, 0xac, 0xe7, 0x77, 0x7a, 0x45, /* 0x00000170: ..l...em.lL..wzE */ 245 0x05, 0x6b, 0x24, 0xf3, 0xaf, 0x45, 0x35, 0x6e, 0x64, 0x0a, 0xac, 0x1d, 0x37, 0xe1, 0x33, 0xa4, /* 0x00000180: .k$..E5nd...7.3. */ 246 0x92, 0xec, 0x45, 0xe8, 0x99, 0xc1, 0xde, 0x6f, 0xab, 0x7c, 0xf0, 0xdc, 0xe2, 0xc5, 0x42, 0xa3, /* 0x00000190: ..E....o.|....B. */ 247 0xea, 0xf5, 0x8a, 0xf9, 0x0e, 0xe7, 0xb3, 0x35, 0xa2, 0x75, 0x5e, 0x87, 0xd2, 0x2a, 0xd1, 0x27, /* 0x000001a0: .......5.u^..*.' */ 248 0xa6, 0x79, 0x9e, 0xfe, 0x90, 0xbf, 0x97, 0xa4, 0xa1, 0xd8, 0xf7, 0xd7, 0x05, 0x59, 0x44, 0x27, /* 0x000001b0: .y...........YD' */ 249 0x39, 0x6e, 0x33, 0x01, 0x2e, 0x46, 0x92, 0x47, 0xbe, 0x50, 0x91, 0x26, 0x27, 0xe5, 0x4b, 0x3a, /* 0x000001c0: 9n3..F.G.P.&'.K: */ 250 0x76, 0x26, 0x64, 0x92, 0x0c, 0xa0, 0x54, 0x43, 0x6f, 0x56, 0xcc, 0x7b, 0xd0, 0xe3, 0xd8, 0x39, /* 0x000001d0: v&d...TCoV.{...9 */ 251 0x5f, 0xb9, 0x41, 0xda, 0x1c, 0x62, 0x88, 0x0c, 0x45, 0x03, 0x63, 0xf8, 0xff, 0xe5, 0x3e, 0x87, /* 0x000001e0: _.A..b..E.c...>. */ 252 0x0c, 0x75, 0xc9, 0xdd, 0xa2, 0xc0, 0x1b, 0x63, 0x19, 0xeb, 0x09, 0x9d, 0xa1, 0xbb, 0x0f, 0x63, /* 0x000001f0: .u.....c.......c */ 253 0x67, 0x1c, 0xa3, 0xfd, 0x2f, 0xd1, 0x2a, 0xda, 0xd8, 0x93, 0x66, 0x45, 0x54, 0xef, 0x8b, 0x6d, /* 0x00000200: g.....*...fET..m */ 254 0x12, 0x15, 0x0f, 0xd4, 0xb5, 0x04, 0x17, 0x30, 0x5b, 0xfa, 0x12, 0x96, 0x48, 0x5b, 0x38, 0x65, /* 0x00000210: .......0[...H[8e */ 255 0xfd, 0x8f, 0x0c, 0xa3, 0x11, 0x46, 0x49, 0xe0, 0x62, 0xc3, 0xcc, 0x34, 0xe6, 0xfb, 0xab, 0x51, /* 0x00000220: .....FI.b..4...Q */ 256 0xc3, 0xd4, 0x0b, 0xdc, 0x39, 0x93, 0x87, 0x90, 0x10, 0x9f, 0xce, 0x43, 0x27, 0x31, 0xd5, 0x4e, /* 0x00000230: ....9......C'1.N */ 257 0x52, 0x60, 0xf1, 0x93, 0xd5, 0x06, 0xc4, 0x4e, 0x65, 0xb6, 0x35, 0x4a, 0x64, 0x15, 0xf8, 0xaf, /* 0x00000240: R`.....Ne.5Jd... */ 258 0x71, 0xb2, 0x42, 0x50, 0x89, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3, 0x46, 0x30, 0x44, 0x30, 0x0e, /* 0x00000250: q.BP.......F0D0. */ 259 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04, 0x04, 0x03, 0x02, 0x07, 0x80, 0x30, 0x13, /* 0x00000260: ..U...........0. */ 260 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x0c, 0x30, 0x0a, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, /* 0x00000270: ..U.%..0...+.... */ 261 0x07, 0x03, 0x08, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x0e, 0x04, 0x16, 0x04, 0x14, 0x52, 0x9d, /* 0x00000280: ...0...U......R. */ 262 0x4d, 0xcd, 0x41, 0xe1, 0xd2, 0x68, 0x22, 0xd3, 0x10, 0x33, 0x01, 0xca, 0xff, 0x00, 0x1d, 0x27, /* 0x00000290: M.A..h"..3.....' */ 263 0xa4, 0x01, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x05, 0x05, /* 0x000002a0: ..0...*.H....... */ 264 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0xc5, 0x5a, 0x51, 0x83, 0x68, 0x3f, 0x06, 0x39, 0x79, 0x13, /* 0x000002b0: .......ZQ.h?.9y. */ 265 0xa6, 0xf0, 0x1a, 0xf9, 0x29, 0x16, 0x2d, 0xa2, 0x07, 0xaa, 0x9b, 0xc3, 0x13, 0x88, 0x39, 0x69, /* 0x000002c0: ....).-.......9i */ 266 0xba, 0xf7, 0x0d, 0xfb, 0xc0, 0x6e, 0x3a, 0x0b, 0x49, 0x10, 0xd1, 0xbe, 0x36, 0x91, 0x3f, 0x9d, /* 0x000002d0: .....n:.I...6.?. */ 267 0xa1, 0xe8, 0xc4, 0x91, 0xf9, 0x02, 0xe1, 0xf1, 0x01, 0x15, 0x09, 0xb7, 0xa1, 0xf1, 0xec, 0x43, /* 0x000002e0: ...............C */ 268 0x0d, 0x73, 0xd1, 0x31, 0x02, 0x4a, 0xce, 0x21, 0xf2, 0xa7, 0x99, 0x7c, 0xee, 0x85, 0x54, 0xc0, /* 0x000002f0: .s.1.J.!...|..T. */ 269 0x55, 0x9b, 0x19, 0x37, 0xe8, 0xcf, 0x94, 0x41, 0x10, 0x6e, 0x67, 0xdd, 0x86, 0xaf, 0xb7, 0xfe, /* 0x00000300: U..7...A.ng..... */ 270 0x50, 0x05, 0xf6, 0xfb, 0x0a, 0xdf, 0x88, 0xb5, 0x59, 0x69, 0x98, 0x27, 0xf8, 0x81, 0x6a, 0x4a, /* 0x00000310: P.......Yi.'..jJ */ 271 0x7c, 0xf3, 0x63, 0xa9, 0x41, 0x78, 0x76, 0x12, 0xdb, 0x0e, 0x94, 0x0a, 0xdb, 0x1d, 0x3c, 0x87, /* 0x00000320: |.c.Axv.......<. */ 272 0x35, 0xca, 0x28, 0xeb, 0xb0, 0x62, 0x27, 0x69, 0xe2, 0xf3, 0x84, 0x48, 0xa2, 0x2d, 0xd7, 0x0e, /* 0x00000330: 5.(..b'i...H.-.. */ 273 0x4b, 0x6d, 0x39, 0xa7, 0x3e, 0x04, 0x94, 0x8e, 0xb6, 0x4b, 0x91, 0x01, 0x68, 0xf9, 0xd2, 0x75, /* 0x00000340: Km9.>....K..h..u */ 274 0x1b, 0xac, 0x42, 0x3b, 0x85, 0xfc, 0x5b, 0x48, 0x3a, 0x13, 0xe7, 0x1c, 0x17, 0xcd, 0x84, 0x89, /* 0x00000350: ..B;..[H:....... */ 275 0x9e, 0x5f, 0xe3, 0x77, 0xc0, 0xae, 0x34, 0xc3, 0x87, 0x76, 0x4a, 0x23, 0x30, 0xa0, 0xe1, 0x45, /* 0x00000360: ._.w..4..vJ#0..E */ 276 0x94, 0x2a, 0x5b, 0x6b, 0x5a, 0xf0, 0x1a, 0x7e, 0xa6, 0xc4, 0xed, 0xe4, 0xac, 0x5d, 0xdf, 0x87, /* 0x00000370: .*[kZ..~.....].. */ 277 0x8f, 0xc5, 0xb4, 0x8c, 0xbc, 0x70, 0xc1, 0xf7, 0xb2, 0x72, 0xbd, 0x73, 0xc9, 0x4e, 0xed, 0x8d, /* 0x00000380: .....p...r.s.N.. */ 278 0x29, 0x33, 0xe9, 0x14, 0xc1, 0x5e, 0xff, 0x39, 0xa8, 0xe7, 0x9a, 0x3b, 0x7a, 0x3c, 0xce, 0x5d, /* 0x00000390: )3...^.9...;z<.] */ 279 0x0f, 0x3c, 0x82, 0x90, 0xff, 0x81, 0x82, 0x00, 0x82, 0x5f, 0xba, 0x08, 0x79, 0xb1, 0x97, 0xc3, /* 0x000003a0: .<......._..y... */ 280 0x09, 0x75, 0xc0, 0x04, 0x9b, 0x67, /* 0x000003b0: .u...g */ 281 }; 282 283 const unsigned char g_abFakeRsaKey[] = 284 { 285 0x30, 0x82, 0x04, 0xa4, 0x02, 0x01, 0x00, 0x02, 0x82, 0x01, 0x01, 0x00, 0xdb, 0x18, 0x63, 0x33, /* 0x00000000: 0.............c3 */ 286 0xf2, 0x08, 0x90, 0x5a, 0xab, 0xda, 0x88, 0x73, 0x86, 0x49, 0xea, 0x8b, 0xaf, 0xcf, 0x67, 0x15, /* 0x00000010: ...Z...s.I....g. */ 287 0xa5, 0x39, 0xe6, 0xa2, 0x94, 0x0c, 0x3f, 0xa1, 0x2e, 0x6c, 0xd2, 0xdf, 0x01, 0x65, 0x6d, 0xed, /* 0x00000020: .9....?..l...em. */ 288 0x6c, 0x4c, 0xac, 0xe7, 0x77, 0x7a, 0x45, 0x05, 0x6b, 0x24, 0xf3, 0xaf, 0x45, 0x35, 0x6e, 0x64, /* 0x00000030: lL..wzE.k$..E5nd */ 289 0x0a, 0xac, 0x1d, 0x37, 0xe1, 0x33, 0xa4, 0x92, 0xec, 0x45, 0xe8, 0x99, 0xc1, 0xde, 0x6f, 0xab, /* 0x00000040: ...7.3...E....o. */ 290 0x7c, 0xf0, 0xdc, 0xe2, 0xc5, 0x42, 0xa3, 0xea, 0xf5, 0x8a, 0xf9, 0x0e, 0xe7, 0xb3, 0x35, 0xa2, /* 0x00000050: |....B........5. */ 291 0x75, 0x5e, 0x87, 0xd2, 0x2a, 0xd1, 0x27, 0xa6, 0x79, 0x9e, 0xfe, 0x90, 0xbf, 0x97, 0xa4, 0xa1, /* 0x00000060: u^..*.'.y....... */ 292 0xd8, 0xf7, 0xd7, 0x05, 0x59, 0x44, 0x27, 0x39, 0x6e, 0x33, 0x01, 0x2e, 0x46, 0x92, 0x47, 0xbe, /* 0x00000070: ....YD'9n3..F.G. */ 293 0x50, 0x91, 0x26, 0x27, 0xe5, 0x4b, 0x3a, 0x76, 0x26, 0x64, 0x92, 0x0c, 0xa0, 0x54, 0x43, 0x6f, /* 0x00000080: P.&'.K:v&d...TCo */ 294 0x56, 0xcc, 0x7b, 0xd0, 0xe3, 0xd8, 0x39, 0x5f, 0xb9, 0x41, 0xda, 0x1c, 0x62, 0x88, 0x0c, 0x45, /* 0x00000090: V.{...9_.A..b..E */ 295 0x03, 0x63, 0xf8, 0xff, 0xe5, 0x3e, 0x87, 0x0c, 0x75, 0xc9, 0xdd, 0xa2, 0xc0, 0x1b, 0x63, 0x19, /* 0x000000a0: .c...>..u.....c. */ 296 0xeb, 0x09, 0x9d, 0xa1, 0xbb, 0x0f, 0x63, 0x67, 0x1c, 0xa3, 0xfd, 0x2f, 0xd1, 0x2a, 0xda, 0xd8, /* 0x000000b0: ......cg.....*.. */ 297 0x93, 0x66, 0x45, 0x54, 0xef, 0x8b, 0x6d, 0x12, 0x15, 0x0f, 0xd4, 0xb5, 0x04, 0x17, 0x30, 0x5b, /* 0x000000c0: .fET..m.......0[ */ 298 0xfa, 0x12, 0x96, 0x48, 0x5b, 0x38, 0x65, 0xfd, 0x8f, 0x0c, 0xa3, 0x11, 0x46, 0x49, 0xe0, 0x62, /* 0x000000d0: ...H[8e.....FI.b */ 299 0xc3, 0xcc, 0x34, 0xe6, 0xfb, 0xab, 0x51, 0xc3, 0xd4, 0x0b, 0xdc, 0x39, 0x93, 0x87, 0x90, 0x10, /* 0x000000e0: ..4...Q....9.... */ 300 0x9f, 0xce, 0x43, 0x27, 0x31, 0xd5, 0x4e, 0x52, 0x60, 0xf1, 0x93, 0xd5, 0x06, 0xc4, 0x4e, 0x65, /* 0x000000f0: ..C'1.NR`.....Ne */ 301 0xb6, 0x35, 0x4a, 0x64, 0x15, 0xf8, 0xaf, 0x71, 0xb2, 0x42, 0x50, 0x89, 0x02, 0x03, 0x01, 0x00, /* 0x00000100: .5Jd...q.BP..... */ 302 0x01, 0x02, 0x82, 0x01, 0x01, 0x00, 0xd0, 0x5e, 0x09, 0x3a, 0xc5, 0xdc, 0xcf, 0x2c, 0xec, 0x74, /* 0x00000110: .......^.:...,.t */ 303 0x11, 0x81, 0x8d, 0x1d, 0x8f, 0x2a, 0xfa, 0x31, 0x4d, 0xe0, 0x90, 0x1a, 0xd8, 0xf5, 0x95, 0xc7, /* 0x00000120: .....*.1M....... */ 304 0x70, 0x5c, 0x62, 0x42, 0xac, 0xe9, 0xd9, 0xf2, 0x14, 0xf1, 0xd0, 0x25, 0xbb, 0xeb, 0x06, 0xfe, /* 0x00000130: p\bB.......%.... */ 305 0x09, 0xd6, 0x75, 0x67, 0xd7, 0x39, 0xc1, 0xa0, 0x67, 0x34, 0x4d, 0xd2, 0x12, 0x97, 0xaa, 0x5d, /* 0x00000140: ..ug.9..g4M....] */ 306 0xeb, 0x0e, 0xb0, 0x16, 0x6c, 0x78, 0x8e, 0xa0, 0x75, 0xa3, 0xaa, 0x57, 0x88, 0x3b, 0x43, 0x4f, /* 0x00000150: ....lx..u..W.;CO */ 307 0x75, 0x85, 0x67, 0xb0, 0x9b, 0xdd, 0x49, 0x0e, 0x6e, 0xdb, 0xea, 0xb3, 0xd4, 0x88, 0x54, 0xa0, /* 0x00000160: u.g...I.n.....T. */ 308 0x46, 0x0d, 0x55, 0x6d, 0x98, 0xbd, 0x20, 0xf9, 0x9f, 0x61, 0x2d, 0x6f, 0xc7, 0xd7, 0x16, 0x66, /* 0x00000170: F.Um.. ..a-o...f */ 309 0x72, 0xc7, 0x73, 0xbe, 0x9e, 0x48, 0xdc, 0x65, 0x12, 0x46, 0x35, 0x69, 0x55, 0xd8, 0x6b, 0x81, /* 0x00000180: r.s..H.e.F5iU.k. */ 310 0x78, 0x40, 0x15, 0x93, 0x60, 0x31, 0x4e, 0x87, 0x15, 0x2a, 0x74, 0x74, 0x7b, 0xa0, 0x1f, 0x59, /* 0x00000190: x@..`1N..*tt{..Y */ 311 0x8d, 0xc8, 0x3f, 0xdd, 0xf0, 0x13, 0x88, 0x2a, 0x4a, 0xf2, 0xf5, 0xf1, 0x9e, 0xf3, 0x2d, 0x9c, /* 0x000001a0: ..?....*J.....-. */ 312 0x8e, 0xbc, 0xb1, 0x21, 0x45, 0xc7, 0x44, 0x0c, 0x6a, 0xfe, 0x4c, 0x20, 0xdc, 0x73, 0xda, 0x62, /* 0x000001b0: ...!E.D.j.L .s.b */ 313 0x21, 0xcb, 0xdf, 0x06, 0xfc, 0x90, 0xc2, 0xbd, 0xd6, 0xde, 0xfb, 0xf6, 0x08, 0x69, 0x5d, 0xea, /* 0x000001c0: !............i]. */ 314 0xb3, 0x7f, 0x93, 0x61, 0xf2, 0xc1, 0xd0, 0x61, 0x4f, 0xd5, 0x5b, 0x63, 0xba, 0xb0, 0x3b, 0x07, /* 0x000001d0: ...a...aO.[c..;. */ 315 0x7a, 0x55, 0xcd, 0xa1, 0xae, 0x8a, 0x92, 0x21, 0xcc, 0x2f, 0x5b, 0xf8, 0x40, 0x6a, 0xcd, 0xd5, /* 0x000001e0: zU.....!..[.@j.. */ 316 0x5f, 0x15, 0xf4, 0xb6, 0xbd, 0xe5, 0x91, 0xb9, 0xa8, 0xcc, 0x2a, 0xa8, 0xa6, 0x67, 0x57, 0x2b, /* 0x000001f0: _.........*..gW+ */ 317 0x4b, 0xe9, 0x88, 0xe0, 0xbb, 0x58, 0xac, 0x69, 0x5f, 0x3c, 0x76, 0x28, 0xa6, 0x9d, 0xbc, 0x71, /* 0x00000200: K....X.i_<v(...q */ 318 0x7f, 0xcb, 0x0c, 0xc0, 0xbd, 0x61, 0x02, 0x81, 0x81, 0x00, 0xfc, 0x62, 0x79, 0x5b, 0xac, 0xf6, /* 0x00000210: .....a.....by[.. */ 319 0x9b, 0x8c, 0xaa, 0x76, 0x2a, 0x30, 0x0e, 0xcf, 0x6b, 0x88, 0x72, 0x54, 0x8c, 0xdf, 0xf3, 0x9d, /* 0x00000220: ...v*0..k.rT.... */ 320 0x84, 0xbb, 0xe7, 0x9d, 0xd4, 0x04, 0x29, 0x3c, 0xb5, 0x9d, 0x60, 0x9a, 0xcc, 0x12, 0xf3, 0xfa, /* 0x00000230: ......)<..`..... */ 321 0x64, 0x30, 0x23, 0x47, 0xc6, 0xa4, 0x8b, 0x6c, 0x73, 0x6c, 0x6b, 0x78, 0x82, 0xec, 0x05, 0x19, /* 0x00000240: d0#G...lslkx.... */ 322 0xde, 0xdd, 0xde, 0x52, 0xc5, 0x20, 0xd1, 0x11, 0x58, 0x19, 0x07, 0x5a, 0x90, 0xdd, 0x22, 0x91, /* 0x00000250: ...R. ..X..Z..". */ 323 0x89, 0x22, 0x3f, 0x12, 0x54, 0x1a, 0xb8, 0x79, 0xd8, 0x6c, 0xbc, 0xf5, 0x0d, 0xc7, 0x73, 0x5c, /* 0x00000260: ."?.T..y.l....s\ */ 324 0xed, 0xba, 0x40, 0x2b, 0x72, 0x34, 0x34, 0x97, 0xfa, 0x49, 0xf6, 0x43, 0x7c, 0xbc, 0x61, 0x30, /* 0x00000270: ..@+r44..I.C|.a0 */ 325 0x54, 0x22, 0x21, 0x5f, 0x77, 0x68, 0x6b, 0x83, 0x95, 0xc6, 0x8d, 0xb8, 0x25, 0x3a, 0xd3, 0xb2, /* 0x00000280: T"!_whk.....%:.. */ 326 0xbe, 0x29, 0x94, 0x01, 0x15, 0xf0, 0x36, 0x9d, 0x3e, 0xff, 0x02, 0x81, 0x81, 0x00, 0xde, 0x3b, /* 0x00000290: .)....6.>......; */ 327 0xd6, 0x4b, 0x38, 0x69, 0x9b, 0x71, 0x29, 0x89, 0xd4, 0x6d, 0x8c, 0x41, 0xee, 0xe2, 0x4d, 0xfc, /* 0x000002a0: .K8i.q)..m.A..M. */ 328 0xf0, 0x9a, 0x73, 0xf1, 0x15, 0x94, 0xac, 0x1b, 0x68, 0x5f, 0x79, 0x15, 0x3a, 0x41, 0x55, 0x09, /* 0x000002b0: ..s.....h_y.:AU. */ 329 0xc7, 0x1e, 0xec, 0x27, 0x67, 0xe2, 0xdc, 0x54, 0xa8, 0x09, 0xe6, 0x46, 0x92, 0x92, 0x03, 0x8d, /* 0x000002c0: ...'g..T...F.... */ 330 0xe5, 0x96, 0xfb, 0x1a, 0xdd, 0x59, 0x6f, 0x92, 0xf1, 0xf6, 0x8f, 0x76, 0xb0, 0xc5, 0xe6, 0xd7, /* 0x000002d0: .....Yo....v.... */ 331 0x1b, 0x25, 0xaf, 0x04, 0x9f, 0xd8, 0x71, 0x27, 0x97, 0x99, 0x23, 0x09, 0x7d, 0xef, 0x06, 0x13, /* 0x000002e0: .%....q'..#.}... */ 332 0xab, 0xdc, 0xa2, 0xd8, 0x5f, 0xc5, 0xec, 0xf3, 0x62, 0x20, 0x72, 0x7b, 0xa8, 0xc7, 0x09, 0x24, /* 0x000002f0: ...._...b r{...$ */ 333 0xaf, 0x72, 0xc9, 0xea, 0xb8, 0x2d, 0xda, 0x00, 0xc8, 0xfe, 0xb4, 0x9f, 0x9f, 0xc7, 0xa9, 0xf7, /* 0x00000300: .r...-.......... */ 334 0x1d, 0xce, 0xb1, 0xdb, 0xc5, 0x8a, 0x4e, 0xe8, 0x88, 0x77, 0x68, 0xdd, 0xf8, 0x77, 0x02, 0x81, /* 0x00000310: ......N..wh..w.. */ 335 0x80, 0x5b, 0xa5, 0x8e, 0x98, 0x01, 0xa8, 0xd3, 0x37, 0x33, 0x37, 0x11, 0x7e, 0xbe, 0x02, 0x07, /* 0x00000320: .[......737.~... */ 336 0xf4, 0x56, 0x3f, 0xe9, 0x9f, 0xf1, 0x20, 0xc3, 0xf0, 0x4f, 0xdc, 0xf9, 0xfe, 0x40, 0xd3, 0x30, /* 0x00000330: .V?... [email protected] */ 337 0xc7, 0xe3, 0x2a, 0x92, 0xec, 0x56, 0xf8, 0x17, 0xa5, 0x7b, 0x4a, 0x37, 0x11, 0xcd, 0x27, 0x26, /* 0x00000340: ..*..V...{J7..'& */ 338 0x8a, 0xba, 0x43, 0xda, 0x96, 0xc6, 0x0b, 0x6c, 0xe8, 0x78, 0x30, 0xea, 0x30, 0x4e, 0x7a, 0xd3, /* 0x00000350: ..C....l.x0.0Nz. */ 339 0xd8, 0xd2, 0xd8, 0xca, 0x3d, 0xe2, 0xad, 0xa2, 0x74, 0x73, 0x1e, 0xbe, 0xb7, 0xad, 0x41, 0x61, /* 0x00000360: ....=...ts....Aa */ 340 0x9b, 0xaa, 0xc9, 0xf9, 0xa4, 0xf1, 0x79, 0x4f, 0x42, 0x10, 0xc7, 0x36, 0x03, 0x4b, 0x0d, 0xdc, /* 0x00000370: ......yOB..6.K.. */ 341 0xef, 0x3a, 0xa3, 0xab, 0x09, 0xe4, 0xe8, 0xdd, 0xc4, 0x3f, 0x06, 0x21, 0xa0, 0x23, 0x5a, 0x76, /* 0x00000380: .:.......?.!.#Zv */ 342 0xea, 0xd0, 0xcf, 0x8b, 0x85, 0x5f, 0x16, 0x4b, 0x03, 0x62, 0x21, 0x3a, 0xcc, 0x2d, 0xa8, 0xd0, /* 0x00000390: ....._.K.b!:.-.. */ 343 0x15, 0x02, 0x81, 0x80, 0x51, 0xf6, 0x89, 0xbb, 0xa6, 0x6b, 0xb4, 0xcb, 0xd0, 0xc1, 0x27, 0xda, /* 0x000003a0: ....Q....k....'. */ 344 0xdb, 0x6e, 0xf9, 0xd6, 0xf7, 0x62, 0x81, 0xae, 0xc5, 0x72, 0x36, 0x3e, 0x66, 0x17, 0x99, 0xb0, /* 0x000003b0: .n...b...r6>f... */ 345 0x14, 0xad, 0x52, 0x96, 0x03, 0xf2, 0x1e, 0x41, 0x76, 0x61, 0xb6, 0x3c, 0x02, 0x7d, 0x2a, 0x98, /* 0x000003c0: ..R....Ava.<.}*. */ 346 0xb4, 0x18, 0x75, 0x38, 0x6b, 0x1d, 0x2b, 0x7f, 0x3a, 0xcf, 0x96, 0xb1, 0xc4, 0xa7, 0xd2, 0x9b, /* 0x000003d0: ..u8k.+.:....... */ 347 0xd8, 0x1f, 0xb3, 0x64, 0xda, 0x15, 0x9d, 0xca, 0x91, 0x39, 0x48, 0x67, 0x00, 0x9c, 0xd4, 0x99, /* 0x000003e0: ...d.....9Hg.... */ 348 0xc3, 0x45, 0x5d, 0xf0, 0x09, 0x32, 0xba, 0x21, 0x1e, 0xe2, 0x64, 0xb8, 0x50, 0x03, 0x17, 0xbe, /* 0x000003f0: .E]..2.!..d.P... */ 349 0xd5, 0xda, 0x6b, 0xce, 0x34, 0xbe, 0x16, 0x03, 0x65, 0x1b, 0x2f, 0xa0, 0xa1, 0x95, 0xc6, 0x8b, /* 0x00000400: ..k.4...e....... */ 350 0xc2, 0x3c, 0x59, 0x26, 0xbf, 0xb6, 0x07, 0x85, 0x53, 0x2d, 0xb6, 0x36, 0xa3, 0x91, 0xb9, 0xbb, /* 0x00000410: .<Y&....S-.6.... */ 351 0x28, 0xaf, 0x2d, 0x53, 0x02, 0x81, 0x81, 0x00, 0xd7, 0xbc, 0x70, 0xd8, 0x18, 0x4f, 0x65, 0x8c, /* 0x00000420: (.-S......p..Oe. */ 352 0x68, 0xca, 0x35, 0x77, 0x43, 0x50, 0x9b, 0xa1, 0xa3, 0x9a, 0x0e, 0x2d, 0x7b, 0x38, 0xf8, 0xba, /* 0x00000430: h.5wCP.....-{8.. */ 353 0x14, 0x91, 0x3b, 0xc3, 0x3b, 0x1b, 0xa0, 0x6d, 0x45, 0xe4, 0xa8, 0x28, 0x97, 0xf6, 0x89, 0x13, /* 0x00000440: ..;.;..mE..(.... */ 354 0xb6, 0x16, 0x6d, 0x65, 0x47, 0x8c, 0xa6, 0x21, 0xf8, 0x6a, 0xce, 0x4e, 0x44, 0x5e, 0x81, 0x47, /* 0x00000450: ..meG..!.j.ND^.G */ 355 0xd9, 0xad, 0x8a, 0xb9, 0xd9, 0xe9, 0x3e, 0x33, 0x1e, 0x5f, 0xe9, 0xe9, 0xa7, 0xea, 0x60, 0x75, /* 0x00000460: ......>3._....`u */ 356 0x02, 0x57, 0x71, 0xb5, 0xed, 0x47, 0x77, 0xda, 0x1a, 0x40, 0x38, 0xab, 0x82, 0xd2, 0x0d, 0xf5, /* 0x00000470: .Wq..Gw..@8..... */ 357 0x0e, 0x8e, 0xa9, 0x24, 0xdc, 0x30, 0xc9, 0x98, 0xa2, 0x05, 0xcd, 0xca, 0x01, 0xcf, 0xae, 0x1d, /* 0x00000480: ...$.0.......... */ 358 0xe9, 0x02, 0x47, 0x0e, 0x46, 0x1d, 0x52, 0x02, 0x9a, 0x99, 0x22, 0x23, 0x7f, 0xf8, 0x9e, 0xc2, /* 0x00000490: ..G.F.R..."#.... */ 359 0x16, 0x86, 0xca, 0xa0, 0xa7, 0x34, 0xfb, 0xbc, /* 0x000004a0: .....4.. */ 360 }; 361 362 363 /** 364 * Certificate w/ public key + private key pair for signing. 365 */ 366 class SignToolKeyPair 367 { 368 protected: 369 /* Context: */ 370 const char *m_pszWhat; 371 bool m_fMandatory; 372 373 /* Parameters kept till finalizing parsing: */ 374 const char *m_pszCertFile; 375 const char *m_pszCertSha1; 376 uint8_t m_abCertSha1[RTSHA1_HASH_SIZE]; 377 const char *m_pszCertSubject; 378 const char *m_pszCertStore; 379 bool m_fMachineStore; /**< false = personal store */ 380 381 const char *m_pszKeyFile; 382 const char *m_pszKeyPassword; 383 const char *m_pszKeyName; 384 const char *m_pszKeyProvider; 385 386 /** String buffer for m_pszKeyPassword when read from file. */ 387 RTCString m_strPassword; 388 /** Storage for pCertificate when it's loaded from a file. */ 389 RTCRX509CERTIFICATE m_DecodedCert; 390 #ifdef RT_OS_WINDOWS 391 /** For the fake certificate */ 392 RTCRX509CERTIFICATE m_DecodedFakeCert; 393 /** The certificate store. */ 394 HCERTSTORE m_hStore; 395 /** The windows certificate context. */ 396 PCCERT_CONTEXT m_pCertCtx; 397 /** Whether hNCryptPrivateKey/hLegacyPrivateKey needs freeing or not. */ 398 BOOL m_fFreePrivateHandle; 399 #endif 400 401 /** Set if already finalized. */ 402 bool m_fFinalized; 403 404 public: /* used to be a struct, thus not prefix either. */ 405 /* Result: */ 406 PCRTCRX509CERTIFICATE pCertificate; 407 RTCRKEY hPrivateKey; 408 #ifdef RT_OS_WINDOWS 409 PCRTCRX509CERTIFICATE pCertificateReal; 410 NCRYPT_KEY_HANDLE hNCryptPrivateKey; 411 HCRYPTPROV hLegacyPrivateKey; 412 #endif 413 414 public: 415 SignToolKeyPair(const char *a_pszWhat, bool a_fMandatory = false) 416 : m_pszWhat(a_pszWhat) 417 , m_fMandatory(a_fMandatory) 418 , m_pszCertFile(NULL) 419 , m_pszCertSha1(NULL) 420 , m_pszCertSubject(NULL) 421 , m_pszCertStore("MY") 422 , m_fMachineStore(false) 423 , m_pszKeyFile(NULL) 424 , m_pszKeyPassword(NULL) 425 , m_pszKeyName(NULL) 426 , m_pszKeyProvider(NULL) 427 #ifdef RT_OS_WINDOWS 428 , m_hStore(NULL) 429 , m_pCertCtx(NULL) 430 , m_fFreePrivateHandle(FALSE) 431 #endif 432 , m_fFinalized(false) 433 , pCertificate(NULL) 434 , hPrivateKey(NIL_RTCRKEY) 435 #ifdef RT_OS_WINDOWS 436 , pCertificateReal(NULL) 437 , hNCryptPrivateKey(0) 438 , hLegacyPrivateKey(0) 439 #endif 440 { 441 RT_ZERO(m_DecodedCert); 442 #ifdef RT_OS_WINDOWS 443 RT_ZERO(m_DecodedFakeCert); 444 #endif 445 } 446 447 ~SignToolKeyPair() 448 { 449 if (hPrivateKey != NIL_RTCRKEY) 450 { 451 RTCrKeyRelease(hPrivateKey); 452 hPrivateKey = NIL_RTCRKEY; 453 } 454 if (pCertificate == &m_DecodedCert) 455 { 456 RTCrX509Certificate_Delete(&m_DecodedCert); 457 pCertificate = NULL; 458 } 459 #ifdef RT_OS_WINDOWS 460 if (pCertificate == &m_DecodedFakeCert) 461 { 462 RTCrX509Certificate_Delete(&m_DecodedFakeCert); 463 RTCrX509Certificate_Delete(&m_DecodedCert); 464 pCertificate = NULL; 465 pCertificateReal = NULL; 466 } 467 #endif 468 #ifdef RT_OS_WINDOWS 469 if (m_pCertCtx != NULL) 470 { 471 CertFreeCertificateContext(m_pCertCtx); 472 m_pCertCtx = NULL; 473 } 474 if (m_hStore != NULL) 475 { 476 CertCloseStore(m_hStore, 0); 477 m_hStore = NULL; 478 } 479 #endif 480 } 481 482 bool isComplete(void) const 483 { 484 return pCertificate && hPrivateKey != NIL_RTCRKEY; 485 } 486 487 bool isNull(void) const 488 { 489 return pCertificate == NULL && hPrivateKey == NIL_RTCRKEY; 490 } 491 492 RTEXITCODE handleOption(unsigned offOpt, PRTGETOPTUNION pValueUnion) 493 { 494 AssertReturn(!m_fFinalized, RTMsgErrorExitFailure("Cannot handle options after finalizeOptions was called!")); 495 switch (offOpt) 496 { 497 case OPT_OFF_CERT_FILE: 498 m_pszCertFile = pValueUnion->psz; 499 m_pszCertSha1 = NULL; 500 m_pszCertSubject = NULL; 501 break; 502 case OPT_OFF_CERT_SHA1: 503 { 504 /* Crude normalization of input separators to colons, since it's likely 505 to use spaces and our conversion function only does colons or nothing. */ 506 char szDigest[RTSHA1_DIGEST_LEN * 3 + 1]; 507 int rc = RTStrCopy(szDigest, sizeof(szDigest), pValueUnion->psz); 508 if (RT_SUCCESS(rc)) 509 { 510 char *pszDigest = RTStrStrip(szDigest); 511 size_t offDst = 0; 512 size_t offSrc = 0; 513 char ch; 514 while ((ch = pszDigest[offSrc++]) != '\0') 515 { 516 if (ch == ' ' || ch == '\t' || ch == ':') 517 { 518 while ((ch = pszDigest[offSrc]) == ' ' || ch == '\t' || ch == ':') 519 offSrc++; 520 ch = ch ? ':' : '\0'; 521 } 522 pszDigest[offDst++] = ch; 523 } 524 pszDigest[offDst] = '\0'; 525 526 /** @todo add a more relaxed input mode to RTStrConvertHexBytes that can deal 527 * with spaces as well as multi-byte cluster of inputs. */ 528 rc = RTStrConvertHexBytes(pszDigest, m_abCertSha1, RTSHA1_HASH_SIZE, RTSTRCONVERTHEXBYTES_F_SEP_COLON); 529 if (RT_SUCCESS(rc)) 530 { 531 m_pszCertFile = NULL; 532 m_pszCertSha1 = pValueUnion->psz; 533 m_pszCertSubject = NULL; 534 break; 535 } 536 } 537 return RTMsgErrorExitFailure("malformed SHA-1 certificate fingerprint (%Rrc): %s", rc, pValueUnion->psz); 538 } 539 case OPT_OFF_CERT_SUBJECT: 540 m_pszCertFile = NULL; 541 m_pszCertSha1 = NULL; 542 m_pszCertSubject = pValueUnion->psz; 543 break; 544 case OPT_OFF_CERT_STORE: 545 m_pszCertStore = pValueUnion->psz; 546 break; 547 case OPT_OFF_CERT_STORE_MACHINE: 548 m_fMachineStore = true; 549 break; 550 551 case OPT_OFF_KEY_FILE: 552 m_pszKeyFile = pValueUnion->psz; 553 m_pszKeyName = NULL; 554 break; 555 case OPT_OFF_KEY_NAME: 556 m_pszKeyFile = NULL; 557 m_pszKeyName = pValueUnion->psz; 558 break; 559 case OPT_OFF_KEY_PROVIDER: 560 m_pszKeyProvider = pValueUnion->psz; 561 break; 562 case OPT_OFF_KEY_PASSWORD: 563 m_pszKeyPassword = pValueUnion->psz; 564 break; 565 case OPT_OFF_KEY_PASSWORD_FILE: 566 { 567 m_pszKeyPassword = NULL; 568 569 size_t const cchMax = 512; 570 int rc = m_strPassword.reserveNoThrow(cchMax + 1); 571 if (RT_FAILURE(rc)) 572 return RTMsgErrorExitFailure("out of memory"); 573 574 PRTSTREAM pStrm = g_pStdIn; 575 bool const fClose = strcmp(pValueUnion->psz, "stdin") != 0; 576 if (fClose) 577 { 578 rc = RTStrmOpen(pValueUnion->psz, "r", &pStrm); 579 if (RT_FAILURE(rc)) 580 return RTMsgErrorExitFailure("Failed to open password file '%s' for reading: %Rrc", pValueUnion->psz, rc); 581 } 582 rc = RTStrmGetLine(pStrm, m_strPassword.mutableRaw(), cchMax); 583 if (fClose) 584 RTStrmClose(pStrm); 585 if (rc == VERR_BUFFER_OVERFLOW || rc == VINF_BUFFER_OVERFLOW) 586 return RTMsgErrorExitFailure("Password from '%s' is too long (max %zu)", pValueUnion->psz, cchMax); 587 if (RT_FAILURE(rc)) 588 return RTMsgErrorExitFailure("Error reading password from '%s': %Rrc", pValueUnion->psz, rc); 589 590 m_strPassword.jolt(); 591 m_strPassword.stripRight(); 592 m_pszKeyPassword = m_strPassword.c_str(); 593 break; 594 } 595 default: 596 AssertFailedReturn(RTMsgErrorExitFailure("Invalid offOpt=%u!\n", offOpt)); 597 } 598 return RTEXITCODE_SUCCESS; 599 } 600 601 RTEXITCODE finalizeOptions(unsigned cVerbosity) 602 { 603 RT_NOREF(cVerbosity); 604 605 /* Only do this once. */ 606 if (m_fFinalized) 607 return RTEXITCODE_SUCCESS; 608 m_fFinalized = true; 609 610 /* 611 * Got a cert? Is it required? 612 */ 613 bool const fHasKey = ( m_pszKeyFile != NULL 614 || m_pszKeyName != NULL); 615 bool const fHasCert = ( m_pszCertFile != NULL 616 || m_pszCertSha1 != NULL 617 || m_pszCertSubject != NULL); 618 if (!fHasCert) 619 { 620 if (m_fMandatory) 621 return RTMsgErrorExit(RTEXITCODE_SYNTAX, "Specifying a %s certificiate is required.", m_pszWhat); 622 return RTEXITCODE_SUCCESS; 623 } 624 625 /* 626 * Get the certificate. 627 */ 628 RTERRINFOSTATIC ErrInfo; 629 /* From file: */ 630 if (m_pszCertFile) 631 { 632 int rc = RTCrX509Certificate_ReadFromFile(&m_DecodedCert, m_pszCertFile, 0, &g_RTAsn1DefaultAllocator, 633 RTErrInfoInitStatic(&ErrInfo)); 634 if (RT_FAILURE(rc)) 635 return RTMsgErrorExitFailure("Error reading %s certificate from '%s': %Rrc%#RTeim", 636 m_pszWhat, m_pszCertFile, rc, &ErrInfo.Core); 637 pCertificate = &m_DecodedCert; 638 } 639 /* From certificate store by name (substring) or fingerprint: */ 640 else 641 { 642 #ifdef RT_OS_WINDOWS 643 m_hStore = CertOpenStore(CERT_STORE_PROV_SYSTEM_A, X509_ASN_ENCODING, NULL, 644 CERT_STORE_DEFER_CLOSE_UNTIL_LAST_FREE_FLAG | CERT_STORE_READONLY_FLAG 645 | CERT_STORE_OPEN_EXISTING_FLAG | CERT_STORE_ENUM_ARCHIVED_FLAG 646 | (m_fMachineStore ? CERT_SYSTEM_STORE_LOCAL_MACHINE : CERT_SYSTEM_STORE_CURRENT_USER), 647 m_pszCertStore); 648 if (m_hStore == NULL) 649 return RTMsgErrorExitFailure("Failed to open %s store '%s': %Rwc (%u)", m_fMachineStore ? "machine" : "user", 650 m_pszCertStore, GetLastError(), GetLastError()); 651 652 CRYPT_HASH_BLOB Thumbprint = { RTSHA1_HASH_SIZE, m_abCertSha1 }; 653 PRTUTF16 pwszSubject = NULL; 654 void const *pvFindParam = &Thumbprint; 655 DWORD fFind = CERT_FIND_SHA1_HASH; 656 if (!m_pszCertSha1) 657 { 658 int rc = RTStrToUtf16(m_pszCertSubject, &pwszSubject); 659 if (RT_FAILURE(rc)) 660 return RTMsgErrorExitFailure("RTStrToUtf16 failed: %Rrc, input %.*Rhxs", 661 rc, strlen(m_pszCertSubject), m_pszCertSubject); 662 pvFindParam = pwszSubject; 663 fFind = CERT_FIND_SUBJECT_STR; 664 } 665 666 while ((m_pCertCtx = CertFindCertificateInStore(m_hStore, X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 0 /*fFlags*/, 667 fFind, pvFindParam, m_pCertCtx)) != NULL) 668 { 669 if (m_pCertCtx->dwCertEncodingType & X509_ASN_ENCODING) 670 { 671 RTASN1CURSORPRIMARY PrimaryCursor; 672 RTAsn1CursorInitPrimary(&PrimaryCursor, m_pCertCtx->pbCertEncoded, m_pCertCtx->cbCertEncoded, 673 RTErrInfoInitStatic(&ErrInfo), 674 &g_RTAsn1DefaultAllocator, RTASN1CURSOR_FLAGS_DER, "CurCtx"); 675 int rc = RTCrX509Certificate_DecodeAsn1(&PrimaryCursor.Cursor, 0, &m_DecodedCert, "Cert"); 676 if (RT_SUCCESS(rc)) 677 { 678 pCertificate = &m_DecodedCert; 679 break; 680 } 681 RTMsgError("failed to decode certificate %p: %Rrc%#RTeim", m_pCertCtx, rc, &ErrInfo.Core); 682 } 683 } 684 685 RTUtf16Free(pwszSubject); 686 if (!m_pCertCtx) 687 return RTMsgErrorExitFailure("No certificate found matching %s '%s' (%Rwc / %u)", 688 m_pszCertSha1 ? "thumbprint" : "subject substring", 689 m_pszCertSha1 ? m_pszCertSha1 : m_pszCertSubject, GetLastError(), GetLastError()); 690 691 /* Use this for private key too? */ 692 if (!fHasKey) 693 { 694 HCRYPTPROV_OR_NCRYPT_KEY_HANDLE hTmpPrivateKey = 0; 695 DWORD dwKeySpec = 0; 696 if (CryptAcquireCertificatePrivateKey(m_pCertCtx, 697 CRYPT_ACQUIRE_SILENT_FLAG | CRYPT_ACQUIRE_COMPARE_KEY_FLAG 698 | CRYPT_ACQUIRE_ALLOW_NCRYPT_KEY_FLAG 699 | CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG, 700 NULL, &hTmpPrivateKey, &dwKeySpec, &m_fFreePrivateHandle)) 701 { 702 if (cVerbosity > 1) 703 RTMsgInfo("hTmpPrivateKey=%p m_fFreePrivateHandle=%d dwKeySpec=%#x", 704 hTmpPrivateKey, m_fFreePrivateHandle, dwKeySpec); 705 Assert(dwKeySpec == CERT_NCRYPT_KEY_SPEC); 706 if (dwKeySpec == CERT_NCRYPT_KEY_SPEC) 707 hNCryptPrivateKey = hTmpPrivateKey; 708 else 709 hLegacyPrivateKey = hTmpPrivateKey; /** @todo remove or drop CRYPT_ACQUIRE_ONLY_NCRYPT_KEY_FLAG */ 710 return loadFakePrivateKeyAndCert(); 711 } 712 return RTMsgErrorExitFailure("CryptAcquireCertificatePrivateKey failed: %Rwc (%d)", GetLastError(), GetLastError()); 713 } 714 #else 715 return RTMsgErrorExitFailure("Certificate store support is missing on this host"); 716 #endif 717 } 718 719 /* 720 * Get hold of the private key (if someone above already did, they'd returned already). 721 */ 722 Assert(hPrivateKey == NIL_RTCRKEY); 723 /* Use cert file if nothing else specified. */ 724 if (!fHasKey && m_pszCertFile) 725 m_pszKeyFile = m_pszCertFile; 726 727 /* Load from file:*/ 728 if (m_pszKeyFile) 729 { 730 int rc = RTCrKeyCreateFromFile(&hPrivateKey, 0 /*fFlags*/, m_pszKeyFile, m_pszKeyPassword, 731 RTErrInfoInitStatic(&ErrInfo)); 732 if (RT_FAILURE(rc)) 733 return RTMsgErrorExitFailure("Error reading the %s private key from '%s': %Rrc%#RTeim", 734 m_pszWhat, m_pszKeyFile, rc, &ErrInfo.Core); 735 } 736 /* From key store: */ 737 else 738 { 739 return RTMsgErrorExitFailure("Key store support is missing on this host"); 740 } 741 742 return RTEXITCODE_SUCCESS; 743 } 744 745 #ifdef RT_OS_WINDOWS 746 RTEXITCODE loadFakePrivateKeyAndCert() 747 { 748 int rc = RTCrX509Certificate_ReadFromBuffer(&m_DecodedFakeCert, g_abFakeCertificate, sizeof(g_abFakeCertificate), 749 0 /*fFlags*/, &g_RTAsn1DefaultAllocator, NULL, NULL); 750 if (RT_FAILURE(rc)) 751 return RTMsgErrorExitFailure("RTCrX509Certificate_ReadFromBuffer/g_abFakeCertificate failed: %Rrc", rc); 752 pCertificateReal = pCertificate; 753 pCertificate = &m_DecodedFakeCert; 754 755 rc = RTCrKeyCreateFromBuffer(&hPrivateKey, 0 /*fFlags*/, g_abFakeRsaKey, sizeof(g_abFakeRsaKey), NULL, NULL, NULL); 756 if (RT_FAILURE(rc)) 757 return RTMsgErrorExitFailure("RTCrKeyCreateFromBuffer/g_abFakeRsaKey failed: %Rrc", rc); 758 return RTEXITCODE_SUCCESS; 759 } 760 761 #endif 762 }; 763 764 765 /********************************************************************************************************************************* 766 * Workers. * 767 *********************************************************************************************************************************/ 195 768 196 769 … … 1237 1810 } 1238 1811 1812 #ifdef RT_OS_WINDOWS 1813 1814 static PCRTUTF16 GetBCryptNameFromCrDigest(RTCRDIGEST hDigest) 1815 { 1816 switch (RTCrDigestGetType(hDigest)) 1817 { 1818 case RTDIGESTTYPE_MD2: return BCRYPT_MD2_ALGORITHM; 1819 case RTDIGESTTYPE_MD4: return BCRYPT_MD4_ALGORITHM; 1820 case RTDIGESTTYPE_SHA1: return BCRYPT_SHA1_ALGORITHM; 1821 case RTDIGESTTYPE_SHA256: return BCRYPT_SHA256_ALGORITHM; 1822 case RTDIGESTTYPE_SHA384: return BCRYPT_SHA384_ALGORITHM; 1823 case RTDIGESTTYPE_SHA512: return BCRYPT_SHA512_ALGORITHM; 1824 default: 1825 RTMsgError("No BCrypt translation for %s/%d!", RTCrDigestGetAlgorithmOid(hDigest), RTCrDigestGetType(hDigest)); 1826 return L"No BCrypt translation"; 1827 } 1828 } 1829 1830 static RTEXITCODE 1831 SignToolPkcs7_Pkcs7SignStuffAgainWithReal(const char *pszWhat, SignToolKeyPair *pCertKeyPair, unsigned cVerbosity, 1832 PRTCRPKCS7CONTENTINFO pContentInfo, void **ppvSigned, size_t *pcbSigned) 1833 1834 { 1835 RT_NOREF(cVerbosity); 1836 1837 /* 1838 * First remove the fake certificate from the PKCS7 structure and insert the real one. 1839 */ 1840 PRTCRPKCS7SIGNEDDATA pSignedData = pContentInfo->u.pSignedData; 1841 unsigned iCert = pSignedData->Certificates.cItems; 1842 while (iCert-- > 0) 1843 { 1844 PCRTCRPKCS7CERT pCert = pSignedData->Certificates.papItems[iCert]; 1845 if ( pCert->enmChoice == RTCRPKCS7CERTCHOICE_X509 1846 && RTCrX509Certificate_MatchIssuerAndSerialNumber(pCert->u.pX509Cert, 1847 &pCertKeyPair->pCertificate->TbsCertificate.Issuer, 1848 &pCertKeyPair->pCertificate->TbsCertificate.SerialNumber)) 1849 RTCrPkcs7SetOfCerts_Erase(&pSignedData->Certificates, iCert); 1850 } 1851 1852 /* Then insert the real signing certificate. */ 1853 RTEXITCODE rcExit = SignToolPkcs7_AppendCertificate(pSignedData, pCertKeyPair->pCertificateReal); 1854 if (rcExit != RTEXITCODE_SUCCESS) 1855 return rcExit; 1856 1857 /* 1858 * Modify the signer info to reflect the real certificate. 1859 */ 1860 PRTCRPKCS7SIGNERINFO pSignerInfo = pSignedData->SignerInfos.papItems[0]; 1861 RTCrX509Name_Delete(&pSignerInfo->IssuerAndSerialNumber.Name); 1862 int rc = RTCrX509Name_Clone(&pSignerInfo->IssuerAndSerialNumber.Name, 1863 &pCertKeyPair->pCertificateReal->TbsCertificate.Issuer, &g_RTAsn1DefaultAllocator); 1864 if (RT_FAILURE(rc)) 1865 return RTMsgErrorExitFailure("(%s) RTCrX509Name_Clone failed: %Rrc", pszWhat, rc); 1866 1867 RTAsn1Integer_Delete(&pSignerInfo->IssuerAndSerialNumber.SerialNumber); 1868 rc = RTAsn1Integer_Clone(&pSignerInfo->IssuerAndSerialNumber.SerialNumber, 1869 &pCertKeyPair->pCertificateReal->TbsCertificate.SerialNumber, &g_RTAsn1DefaultAllocator); 1870 if (RT_FAILURE(rc)) 1871 return RTMsgErrorExitFailure("(%s) RTAsn1Integer_Clone failed: %Rrc", pszWhat, rc); 1872 1873 /* There shouldn't be anything in the authenticated attributes that 1874 we need to modify... */ 1875 1876 /* 1877 * Now a create a new signature using the real key. Since we haven't modified 1878 * the authenticated attributes, we can just hash them as-is. 1879 */ 1880 /* Create the hash to sign. */ 1881 RTCRDIGEST hDigest; 1882 rc = RTCrDigestCreateByObjId(&hDigest, &pSignerInfo->DigestAlgorithm.Algorithm); 1883 if (RT_FAILURE(rc)) 1884 return RTMsgErrorExitFailure("(%s) RTCrDigestCreateByObjId failed on '%s': %Rrc", 1885 pszWhat, pSignerInfo->DigestAlgorithm.Algorithm.szObjId, rc); 1886 1887 rcExit = RTEXITCODE_FAILURE; 1888 RTERRINFOSTATIC ErrInfo; 1889 rc = RTCrPkcs7Attributes_HashAttributes(&pSignerInfo->AuthenticatedAttributes, hDigest, RTErrInfoInitStatic(&ErrInfo)); 1890 if (RT_SUCCESS(rc)) 1891 { 1892 BCRYPT_PKCS1_PADDING_INFO PaddingInfo = { GetBCryptNameFromCrDigest(hDigest) }; 1893 DWORD cbSignature = 0; 1894 SECURITY_STATUS rcNCrypt = NCryptSignHash(pCertKeyPair->hNCryptPrivateKey, &PaddingInfo, 1895 (PBYTE)RTCrDigestGetHash(hDigest), RTCrDigestGetHashSize(hDigest), 1896 NULL, 0, &cbSignature, NCRYPT_SILENT_FLAG | BCRYPT_PAD_PKCS1); 1897 if (rcNCrypt == ERROR_SUCCESS) 1898 { 1899 if (cVerbosity) 1900 RTMsgInfo("PaddingInfo: '%ls' cb=%#x, was %#zx\n", 1901 PaddingInfo.pszAlgId, cbSignature, pSignerInfo->EncryptedDigest.Asn1Core.cb); 1902 1903 rc = RTAsn1OctetString_AllocContent(&pSignerInfo->EncryptedDigest, NULL /*pvSrc*/, cbSignature, 1904 &g_RTAsn1DefaultAllocator); 1905 if (RT_SUCCESS(rc)) 1906 { 1907 Assert(pSignerInfo->EncryptedDigest.Asn1Core.uData.pv); 1908 rcNCrypt = NCryptSignHash(pCertKeyPair->hNCryptPrivateKey, &PaddingInfo, 1909 (PBYTE)RTCrDigestGetHash(hDigest), RTCrDigestGetHashSize(hDigest), 1910 (PBYTE)pSignerInfo->EncryptedDigest.Asn1Core.uData.pv, cbSignature, &cbSignature, 1911 /*NCRYPT_SILENT_FLAG |*/ BCRYPT_PAD_PKCS1); 1912 if (rcNCrypt == ERROR_SUCCESS) 1913 { 1914 /* 1915 * Now we need to re-encode the whole thing and decode it again. 1916 */ 1917 PRTASN1CORE pRoot = RTCrPkcs7ContentInfo_GetAsn1Core(pContentInfo); 1918 uint32_t cbRealSigned; 1919 rc = RTAsn1EncodePrepare(pRoot, RTASN1ENCODE_F_DER, &cbRealSigned, RTErrInfoInitStatic(&ErrInfo)); 1920 if (RT_SUCCESS(rc)) 1921 { 1922 void *pvRealSigned = RTMemAllocZ(cbRealSigned); 1923 if (pvRealSigned) 1924 { 1925 rc = RTAsn1EncodeToBuffer(pRoot, RTASN1ENCODE_F_DER, pvRealSigned, cbRealSigned, 1926 RTErrInfoInitStatic(&ErrInfo)); 1927 if (RT_SUCCESS(rc)) 1928 { 1929 /* Decode it */ 1930 RTCrPkcs7ContentInfo_Delete(pContentInfo); 1931 1932 RTASN1CURSORPRIMARY PrimaryCursor; 1933 RTAsn1CursorInitPrimary(&PrimaryCursor, pvRealSigned, cbRealSigned, RTErrInfoInitStatic(&ErrInfo), 1934 &g_RTAsn1DefaultAllocator, 0, pszWhat); 1935 rc = RTCrPkcs7ContentInfo_DecodeAsn1(&PrimaryCursor.Cursor, 0, pContentInfo, "CI"); 1936 if (RT_SUCCESS(rc)) 1937 { 1938 Assert(RTCrPkcs7ContentInfo_IsSignedData(pContentInfo)); 1939 1940 /* Almost done! Just replace output buffer. */ 1941 RTMemFree(*ppvSigned); 1942 *ppvSigned = pvRealSigned; 1943 *pcbSigned = cbRealSigned; 1944 pvRealSigned = NULL; 1945 rcExit = RTEXITCODE_SUCCESS; 1946 } 1947 else 1948 RTMsgError("(%s) RTCrPkcs7ContentInfo_DecodeAsn1 failed: %Rrc%#RTeim", 1949 pszWhat, rc, &ErrInfo.Core); 1950 } 1951 else 1952 RTMsgError("(%s) RTAsn1EncodeToBuffer failed: %Rrc%#RTeim", pszWhat, rc, &ErrInfo.Core); 1953 1954 RTMemFree(pvRealSigned); 1955 } 1956 else 1957 RTMsgError("(%s) Failed to allocate %u bytes!", pszWhat, cbRealSigned); 1958 } 1959 else 1960 RTMsgError("(%s) RTAsn1EncodePrepare failed: %Rrc%#RTeim", pszWhat, rc, &ErrInfo.Core); 1961 } 1962 else 1963 RTMsgError("(%s) NCryptSignHash/2 failed: %Rwc %#x (%u)", pszWhat, rcNCrypt, rcNCrypt, rcNCrypt); 1964 } 1965 else 1966 RTMsgError("(%s) RTAsn1OctetString_AllocContent(,,%#x) failed: %Rrc", pszWhat, cbSignature, rc); 1967 } 1968 else 1969 RTMsgError("(%s) NCryptSignHash/1 failed: %Rwc %#x (%u)", pszWhat, rcNCrypt, rcNCrypt, rcNCrypt); 1970 } 1971 else 1972 RTMsgError("(%s) RTCrPkcs7Attributes_HashAttributes failed: %Rrc%#RTeim", pszWhat, rc, &ErrInfo.Core); 1973 RTCrDigestRelease(hDigest); 1974 return rcExit; 1975 } 1976 1977 #endif /* RT_OS_WINDOWS */ 1239 1978 1240 1979 static RTEXITCODE SignToolPkcs7_Pkcs7SignStuff(const char *pszWhat, const void *pvToDataToSign, size_t cbToDataToSign, 1241 1980 PCRTCRPKCS7ATTRIBUTES pAuthAttribs, RTCRSTORE hAdditionalCerts, 1242 uint32_t fExtraFlags, RTDIGESTTYPE enmDigestType, S IGNTOOLKEYPAIR*pCertKeyPair,1981 uint32_t fExtraFlags, RTDIGESTTYPE enmDigestType, SignToolKeyPair *pCertKeyPair, 1243 1982 unsigned cVerbosity, void **ppvSigned, size_t *pcbSigned, 1244 1983 PRTCRPKCS7CONTENTINFO pContentInfo, PRTCRPKCS7SIGNEDDATA *ppSignedData) … … 1258 1997 NULL, &cbSigned, RTErrInfoInitStatic(&ErrInfo)); 1259 1998 if (rc != VERR_BUFFER_OVERFLOW) 1260 return RTMsgErrorExitFailure(" RTCrPkcs7SimpleSignSignedData failed: %Rrc%#RTeim", rc, &ErrInfo.Core);1999 return RTMsgErrorExitFailure("(%s) RTCrPkcs7SimpleSignSignedData failed: %Rrc%#RTeim", pszWhat, rc, &ErrInfo.Core); 1261 2000 1262 2001 /* Allocate memory for it and do the actual signing. */ 1263 2002 void *pvSigned = RTMemAllocZ(cbSigned); 1264 2003 if (!pvSigned) 1265 return RTMsgErrorExitFailure(" Failed to allocate %#zx bytes for %s signature", cbSigned, pszWhat);2004 return RTMsgErrorExitFailure("(%s) Failed to allocate %#zx bytes for %s signature", pszWhat, cbSigned, pszWhat); 1266 2005 rc = RTCrPkcs7SimpleSignSignedData(fSignFlags, pCertKeyPair->pCertificate, pCertKeyPair->hPrivateKey, 1267 2006 pvToDataToSign, cbToDataToSign, enmDigestType, hAdditionalCerts, pAuthAttribs, … … 1283 2022 if (RTCrPkcs7ContentInfo_IsSignedData(pContentInfo)) 1284 2023 { 1285 *ppvSigned = pvSigned; 1286 if (pcbSigned) 1287 *pcbSigned = cbSigned; 1288 if (ppSignedData) 1289 *ppSignedData = pContentInfo->u.pSignedData; 1290 1291 if (cVerbosity) 2024 #ifdef RT_OS_WINDOWS 2025 /* 2026 * If we're using a fake key+cert, we now have to re-do the signing using the real 2027 * key+cert and the windows crypto API. This kludge is necessary because we can't 2028 * typically get that the encoded private key, so it isn't possible to feed it to 2029 * openssl. 2030 */ 2031 RTEXITCODE rcExit = RTEXITCODE_SUCCESS; 2032 if (pCertKeyPair->pCertificateReal) 2033 rcExit = SignToolPkcs7_Pkcs7SignStuffAgainWithReal(pszWhat, pCertKeyPair, cVerbosity, pContentInfo, 2034 &pvSigned, &cbSigned); 2035 if (rcExit == RTEXITCODE_SUCCESS) 2036 #endif 1292 2037 { 1293 SHOWEXEPKCS7 ShowExe; 1294 RT_ZERO(ShowExe); 1295 ShowExe.cVerbosity = cVerbosity; 1296 HandleShowExeWorkerPkcs7Display(&ShowExe, pContentInfo->u.pSignedData, 0, pContentInfo); 2038 /* 2039 * Set returns and maybe display the result before returning. 2040 */ 2041 *ppvSigned = pvSigned; 2042 if (pcbSigned) 2043 *pcbSigned = cbSigned; 2044 if (ppSignedData) 2045 *ppSignedData = pContentInfo->u.pSignedData; 2046 2047 if (cVerbosity) 2048 { 2049 SHOWEXEPKCS7 ShowExe; 2050 RT_ZERO(ShowExe); 2051 ShowExe.cVerbosity = cVerbosity; 2052 HandleShowExeWorkerPkcs7Display(&ShowExe, pContentInfo->u.pSignedData, 0, pContentInfo); 2053 } 2054 return RTEXITCODE_SUCCESS; 1297 2055 } 1298 return RTEXITCODE_SUCCESS;1299 2056 } 1300 2057 1301 RTMsgError("RTCrPkcs7SimpleSignSignedData did not create SignedData: %s", pContentInfo->ContentType.szObjId); 2058 RTMsgError("(%s) RTCrPkcs7SimpleSignSignedData did not create SignedData: %s", 2059 pszWhat, pContentInfo->ContentType.szObjId); 1302 2060 } 1303 2061 else 1304 RTMsgError(" RTCrPkcs7ContentInfo_DecodeAsn1 failed: %Rrc%#RTeim", rc, &ErrInfo.Core);2062 RTMsgError("(%s) RTCrPkcs7ContentInfo_DecodeAsn1 failed: %Rrc%#RTeim", pszWhat, rc, &ErrInfo.Core); 1305 2063 RTCrPkcs7ContentInfo_Delete(pContentInfo); 1306 2064 } … … 1312 2070 static RTEXITCODE SignToolPkcs7_AddTimestampSignatureEx(PRTCRPKCS7SIGNERINFO pSignerInfo, PRTCRPKCS7SIGNEDDATA pSignedData, 1313 2071 unsigned cVerbosity, bool fReplaceExisting, bool fTimestampTypeOld, 1314 RTTIMESPEC SigningTime, S IGNTOOLKEYPAIR*pTimestampPair)2072 RTTIMESPEC SigningTime, SignToolKeyPair *pTimestampPair) 1315 2073 { 1316 2074 AssertReturn(fTimestampTypeOld, RTMsgErrorExitFailure("New style signatures not supported yet")); … … 1390 2148 static RTEXITCODE SignToolPkcs7_AddTimestampSignature(SIGNTOOLPKCS7EXE *pThis, unsigned cVerbosity, unsigned iSignature, 1391 2149 bool fReplaceExisting, bool fTimestampTypeOld, RTTIMESPEC SigningTime, 1392 S IGNTOOLKEYPAIR*pTimestampPair)2150 SignToolKeyPair *pTimestampPair) 1393 2151 { 1394 2152 AssertReturn(fTimestampTypeOld, RTMsgErrorExitFailure("New style signatures not supported yet")); … … 1409 2167 static RTEXITCODE SignToolPkcs7_SignData(SIGNTOOLPKCS7 *pThis, PRTASN1CORE pToSignRoot, bool fIsRootsParent, 1410 2168 const char *pszContentTypeId, unsigned cVerbosity, RTDIGESTTYPE enmSigType, 1411 bool fReplaceExisting, S IGNTOOLKEYPAIR*pSigningCertKey, RTCRSTORE hAddCerts,1412 bool fTimestampTypeOld, RTTIMESPEC SigningTime, S IGNTOOLKEYPAIR*pTimestampCertKey)2169 bool fReplaceExisting, SignToolKeyPair *pSigningCertKey, RTCRSTORE hAddCerts, 2170 bool fTimestampTypeOld, RTTIMESPEC SigningTime, SignToolKeyPair *pTimestampCertKey) 1413 2171 { 1414 2172 /* … … 1712 2470 1713 2471 static RTEXITCODE SignToolPkcs7_AddOrReplaceSignature(SIGNTOOLPKCS7EXE *pThis, unsigned cVerbosity, RTDIGESTTYPE enmSigType, 1714 bool fReplaceExisting, bool fHashPages, S IGNTOOLKEYPAIR*pSigningCertKey,2472 bool fReplaceExisting, bool fHashPages, SignToolKeyPair *pSigningCertKey, 1715 2473 RTCRSTORE hAddCerts, bool fTimestampTypeOld, 1716 RTTIMESPEC SigningTime, S IGNTOOLKEYPAIR*pTimestampCertKey)2474 RTTIMESPEC SigningTime, SignToolKeyPair *pTimestampCertKey) 1717 2475 { 1718 2476 AssertReturn(fTimestampTypeOld || pTimestampCertKey->isNull(), … … 1798 2556 1799 2557 static RTEXITCODE SignToolPkcs7_AddOrReplaceCatSignature(SIGNTOOLPKCS7 *pThis, unsigned cVerbosity, RTDIGESTTYPE enmSigType, 1800 bool fReplaceExisting, S IGNTOOLKEYPAIR*pSigningCertKey,2558 bool fReplaceExisting, SignToolKeyPair *pSigningCertKey, 1801 2559 RTCRSTORE hAddCerts, bool fTimestampTypeOld, 1802 RTTIMESPEC SigningTime, S IGNTOOLKEYPAIR*pTimestampCertKey)2560 RTTIMESPEC SigningTime, SignToolKeyPair *pTimestampCertKey) 1803 2561 { 1804 2562 AssertReturn(fTimestampTypeOld || pTimestampCertKey->isNull(), … … 2298 3056 #ifndef IPRT_IN_BUILD_TOOL 2299 3057 2300 static RTEXITCODE HandleOptCertFile(SIGNTOOLKEYPAIR *pKeyPair, const char *pszFile)2301 {2302 if (pKeyPair->pCertificate == &pKeyPair->Cert)2303 RTCrX509Certificate_Delete(&pKeyPair->Cert);2304 pKeyPair->pCertificate = NULL;2305 2306 RTERRINFOSTATIC ErrInfo;2307 int rc = RTCrX509Certificate_ReadFromFile(&pKeyPair->Cert, pszFile, 0, &g_RTAsn1DefaultAllocator,2308 RTErrInfoInitStatic(&ErrInfo));2309 if (RT_FAILURE(rc))2310 return RTMsgErrorExitFailure("Error reading certificate from '%s': %Rrc%#RTeim", pszFile, rc, &ErrInfo.Core);2311 pKeyPair->pCertificate = &pKeyPair->Cert;2312 return RTEXITCODE_SUCCESS;2313 }2314 2315 static RTEXITCODE HandleOptKeyFile(SIGNTOOLKEYPAIR *pKeyPair, const char *pszFile)2316 {2317 RTCrKeyRelease(pKeyPair->hPrivateKey);2318 2319 RTERRINFOSTATIC ErrInfo;2320 int rc = RTCrKeyCreateFromFile(&pKeyPair->hPrivateKey, 0 /*fFlags*/, pszFile,2321 NULL /*pszPassword*/, RTErrInfoInitStatic(&ErrInfo));2322 if (RT_SUCCESS(rc))2323 return RTEXITCODE_SUCCESS;2324 2325 pKeyPair->hPrivateKey = NIL_RTCRKEY;2326 return RTMsgErrorExitFailure("Error reading private key from '%s': %Rrc%#RTeim", pszFile, rc, &ErrInfo.Core);2327 }2328 2329 3058 static RTEXITCODE HandleOptAddCert(PRTCRSTORE phStore, const char *pszFile) 2330 3059 { … … 2445 3174 RTStrmWrappedPrintf(pStrm, RTSTRMWRAPPED_F_HANGING_INDENT, 2446 3175 "add-timestamp-exe-signature [-v|--verbose] [--signature-index|-i <num>] " 2447 "[--timestamp-cert-file <file>] " 2448 "[--timestamp-key-file <file>] " 3176 OPT_CERT_KEY_SYNOPSIS("--timestamp-") 2449 3177 "[--timestamp-type old|new] " 2450 3178 "[--timestamp-date <fake-isots>] " … … 2470 3198 { 2471 3199 { "--signature-index", 'i', RTGETOPT_REQ_UINT32 }, 2472 { "--timestamp-cert-file", OPT_TIMESTAMP_CERT_FILE, RTGETOPT_REQ_STRING }, 2473 { "--timestamp-key-file", OPT_TIMESTAMP_KEY_FILE, RTGETOPT_REQ_STRING }, 3200 OPT_CERT_KEY_GETOPTDEF_ENTRIES("--timestamp-", 1000), 2474 3201 { "--timestamp-type", OPT_TIMESTAMP_TYPE, RTGETOPT_REQ_STRING }, 2475 3202 { "--timestamp-override", OPT_TIMESTAMP_OVERRIDE, RTGETOPT_REQ_STRING }, … … 2482 3209 bool fReplaceExisting = false; 2483 3210 bool fTimestampTypeOld = true; 2484 S IGNTOOLKEYPAIR TimestampCertKey;3211 SignToolKeyPair TimestampCertKey("timestamp", true); 2485 3212 RTTIMESPEC SigningTime; 2486 3213 RTTimeNow(&SigningTime); … … 2498 3225 switch (ch) 2499 3226 { 3227 OPT_CERT_KEY_SWITCH_CASES(TimestampCertKey, 1000, ch, ValueUnion, rcExit2); 2500 3228 case 'i': iSignature = ValueUnion.u32; break; 2501 case OPT_TIMESTAMP_CERT_FILE: rcExit2 = HandleOptCertFile(&TimestampCertKey, ValueUnion.psz); break;2502 case OPT_TIMESTAMP_KEY_FILE: rcExit2 = HandleOptKeyFile(&TimestampCertKey, ValueUnion.psz); break;2503 3229 case OPT_TIMESTAMP_TYPE: rcExit2 = HandleOptTimestampType(&fTimestampTypeOld, ValueUnion.psz); break; 2504 3230 case OPT_TIMESTAMP_OVERRIDE: rcExit2 = HandleOptTimestampOverride(&SigningTime, ValueUnion.psz); break; … … 2509 3235 2510 3236 case VINF_GETOPT_NOT_OPTION: 2511 /* check that we've got all the info we need: */ 2512 if (TimestampCertKey.isComplete()) 3237 /* Do final certificate and key option processing (first file only). */ 3238 rcExit2 = TimestampCertKey.finalizeOptions(cVerbosity); 3239 if (rcExit2 == RTEXITCODE_SUCCESS) 2513 3240 { 2514 3241 /* Do the work: */ … … 2529 3256 rcExit2 = RTEXITCODE_SUCCESS; 2530 3257 } 2531 else2532 {2533 if (!TimestampCertKey.pCertificate)2534 RTMsgError("No timestamp certificate was specified");2535 if (TimestampCertKey.hPrivateKey == NIL_RTCRKEY)2536 RTMsgError("No timestamp private key was specified");2537 rcExit2 = RTEXITCODE_SYNTAX;2538 }2539 3258 break; 2540 3259 … … 2570 3289 "[--no-hash-pages] " 2571 3290 "[--append] " 2572 "[--cert-file <file>] " 2573 "[--cert-key <file>] " 3291 OPT_CERT_KEY_SYNOPSIS("--") 2574 3292 "[--add-cert <file>] " 2575 "[--timestamp-cert-file <file>] " 2576 "[--timestamp-key-file <file>] " 3293 OPT_CERT_KEY_SYNOPSIS("--timestamp-") 2577 3294 "[--timestamp-type old|new] " 2578 3295 "[--timestamp-date <fake-isots>] " … … 2608 3325 { "--add-cert", OPT_ADD_CERT, RTGETOPT_REQ_STRING }, 2609 3326 { "/ac", OPT_ADD_CERT, RTGETOPT_REQ_STRING }, 2610 { "--cert-file", OPT_CERT_FILE, RTGETOPT_REQ_STRING }, 2611 { "--key-file", OPT_KEY_FILE, RTGETOPT_REQ_STRING }, 2612 { "--timestamp-cert-file", OPT_TIMESTAMP_CERT_FILE, RTGETOPT_REQ_STRING }, 2613 { "--timestamp-key-file", OPT_TIMESTAMP_KEY_FILE, RTGETOPT_REQ_STRING }, 3327 OPT_CERT_KEY_GETOPTDEF_ENTRIES("--", 1000), 3328 OPT_CERT_KEY_GETOPTDEF_COMPAT_ENTRIES( 1000), 3329 OPT_CERT_KEY_GETOPTDEF_ENTRIES("--timestamp-", 1020), 2614 3330 { "--timestamp-type", OPT_TIMESTAMP_TYPE, RTGETOPT_REQ_STRING }, 2615 3331 { "--timestamp-override", OPT_TIMESTAMP_OVERRIDE, RTGETOPT_REQ_STRING }, … … 2623 3339 bool fReplaceExisting = true; 2624 3340 bool fHashPages = false; 2625 S IGNTOOLKEYPAIR SigningCertKey;3341 SignToolKeyPair SigningCertKey("signing", true); 2626 3342 RTCRSTORE hAddCerts = NIL_RTCRSTORE; /* leaked if returning directly (--help, --version) */ 2627 3343 bool fTimestampTypeOld = true; 2628 S IGNTOOLKEYPAIR TimestampCertKey;3344 SignToolKeyPair TimestampCertKey("timestamp"); 2629 3345 RTTIMESPEC SigningTime; 2630 3346 RTTimeNow(&SigningTime); … … 2642 3358 switch (ch) 2643 3359 { 3360 OPT_CERT_KEY_SWITCH_CASES(SigningCertKey, 1000, ch, ValueUnion, rcExit2); 3361 OPT_CERT_KEY_SWITCH_CASES(TimestampCertKey, 1020, ch, ValueUnion, rcExit2); 2644 3362 case 't': rcExit2 = HandleOptSignatureType(&enmSigType, ValueUnion.psz); break; 2645 3363 case 'a': fReplaceExisting = false; break; 2646 3364 case OPT_HASH_PAGES: fHashPages = true; break; 2647 3365 case OPT_NO_HASH_PAGES: fHashPages = false; break; 2648 case OPT_CERT_FILE: rcExit2 = HandleOptCertFile(&SigningCertKey, ValueUnion.psz); break;2649 case OPT_KEY_FILE: rcExit2 = HandleOptKeyFile(&SigningCertKey, ValueUnion.psz); break;2650 3366 case OPT_ADD_CERT: rcExit2 = HandleOptAddCert(&hAddCerts, ValueUnion.psz); break; 2651 case OPT_TIMESTAMP_CERT_FILE: rcExit2 = HandleOptCertFile(&TimestampCertKey, ValueUnion.psz); break;2652 case OPT_TIMESTAMP_KEY_FILE: rcExit2 = HandleOptKeyFile(&TimestampCertKey, ValueUnion.psz); break;2653 3367 case OPT_TIMESTAMP_TYPE: rcExit2 = HandleOptTimestampType(&fTimestampTypeOld, ValueUnion.psz); break; 2654 3368 case OPT_TIMESTAMP_OVERRIDE: rcExit2 = HandleOptTimestampOverride(&SigningTime, ValueUnion.psz); break; … … 2658 3372 2659 3373 case VINF_GETOPT_NOT_OPTION: 2660 /* check that we've got all the info we need: */ 2661 if ( SigningCertKey.isComplete() 2662 && (TimestampCertKey.isNull() || TimestampCertKey.isComplete())) 3374 /* Do final certificate and key option processing (first file only). */ 3375 rcExit2 = SigningCertKey.finalizeOptions(cVerbosity); 3376 if (rcExit2 == RTEXITCODE_SUCCESS) 3377 rcExit2 = TimestampCertKey.finalizeOptions(cVerbosity); 3378 if (rcExit2 == RTEXITCODE_SUCCESS) 2663 3379 { 2664 3380 /* Do the work: */ … … 2681 3397 rcExit2 = RTEXITCODE_SUCCESS; 2682 3398 } 2683 else2684 {2685 if (!TimestampCertKey.pCertificate)2686 RTMsgError("No signing certificate was specified");2687 if (TimestampCertKey.hPrivateKey == NIL_RTCRKEY)2688 RTMsgError("No signing private key was specified");2689 2690 if (!TimestampCertKey.pCertificate && !TimestampCertKey.isNull())2691 RTMsgError("No timestamp certificate was specified");2692 if (TimestampCertKey.hPrivateKey == NIL_RTCRKEY && !TimestampCertKey.isNull())2693 RTMsgError("No timestamp private key was specified");2694 rcExit2 = RTEXITCODE_SYNTAX;2695 }2696 3399 break; 2697 3400 … … 2724 3427 2725 3428 RTStrmWrappedPrintf(pStrm, RTSTRMWRAPPED_F_HANGING_INDENT, 2726 "sign- exe[-v|--verbose] "3429 "sign-cat [-v|--verbose] " 2727 3430 "[--type sha1|sha256] " 2728 3431 "[--append] " 2729 "[--cert-file <file>] " 2730 "[--cert-key <file>] " 3432 OPT_CERT_KEY_SYNOPSIS("--") 2731 3433 "[--add-cert <file>] " 2732 "[--timestamp-cert-file <file>] " 2733 "[--timestamp-key-file <file>] " 3434 OPT_CERT_KEY_SYNOPSIS("--timestamp-") 2734 3435 "[--timestamp-type old|new] " 2735 3436 "[--timestamp-date <fake-isots>] " … … 2761 3462 { "--add-cert", OPT_ADD_CERT, RTGETOPT_REQ_STRING }, 2762 3463 { "/ac", OPT_ADD_CERT, RTGETOPT_REQ_STRING }, 2763 { "--cert-file", OPT_CERT_FILE, RTGETOPT_REQ_STRING }, 2764 { "--key-file", OPT_KEY_FILE, RTGETOPT_REQ_STRING }, 2765 { "--timestamp-cert-file", OPT_TIMESTAMP_CERT_FILE, RTGETOPT_REQ_STRING }, 2766 { "--timestamp-key-file", OPT_TIMESTAMP_KEY_FILE, RTGETOPT_REQ_STRING }, 3464 OPT_CERT_KEY_GETOPTDEF_ENTRIES("--", 1000), 3465 OPT_CERT_KEY_GETOPTDEF_COMPAT_ENTRIES( 1000), 3466 OPT_CERT_KEY_GETOPTDEF_ENTRIES("--timestamp-", 1020), 2767 3467 { "--timestamp-type", OPT_TIMESTAMP_TYPE, RTGETOPT_REQ_STRING }, 2768 3468 { "--timestamp-override", OPT_TIMESTAMP_OVERRIDE, RTGETOPT_REQ_STRING }, … … 2775 3475 RTDIGESTTYPE enmSigType = RTDIGESTTYPE_SHA1; 2776 3476 bool fReplaceExisting = true; 2777 S IGNTOOLKEYPAIR SigningCertKey;3477 SignToolKeyPair SigningCertKey("signing", true); 2778 3478 RTCRSTORE hAddCerts = NIL_RTCRSTORE; /* leaked if returning directly (--help, --version) */ 2779 3479 bool fTimestampTypeOld = true; 2780 S IGNTOOLKEYPAIR TimestampCertKey;3480 SignToolKeyPair TimestampCertKey("timestamp"); 2781 3481 RTTIMESPEC SigningTime; 2782 3482 RTTimeNow(&SigningTime); … … 2794 3494 switch (ch) 2795 3495 { 3496 OPT_CERT_KEY_SWITCH_CASES(SigningCertKey, 1000, ch, ValueUnion, rcExit2); 3497 OPT_CERT_KEY_SWITCH_CASES(TimestampCertKey, 1020, ch, ValueUnion, rcExit2); 2796 3498 case 't': rcExit2 = HandleOptSignatureType(&enmSigType, ValueUnion.psz); break; 2797 3499 case 'a': fReplaceExisting = false; break; 2798 case OPT_CERT_FILE: rcExit2 = HandleOptCertFile(&SigningCertKey, ValueUnion.psz); break;2799 case OPT_KEY_FILE: rcExit2 = HandleOptKeyFile(&SigningCertKey, ValueUnion.psz); break;2800 3500 case OPT_ADD_CERT: rcExit2 = HandleOptAddCert(&hAddCerts, ValueUnion.psz); break; 2801 case OPT_TIMESTAMP_CERT_FILE: rcExit2 = HandleOptCertFile(&TimestampCertKey, ValueUnion.psz); break;2802 case OPT_TIMESTAMP_KEY_FILE: rcExit2 = HandleOptKeyFile(&TimestampCertKey, ValueUnion.psz); break;2803 3501 case OPT_TIMESTAMP_TYPE: rcExit2 = HandleOptTimestampType(&fTimestampTypeOld, ValueUnion.psz); break; 2804 3502 case OPT_TIMESTAMP_OVERRIDE: rcExit2 = HandleOptTimestampOverride(&SigningTime, ValueUnion.psz); break; … … 2808 3506 2809 3507 case VINF_GETOPT_NOT_OPTION: 2810 /* check that we've got all the info we need: */ 2811 if ( SigningCertKey.isComplete() 2812 && (TimestampCertKey.isNull() || TimestampCertKey.isComplete())) 3508 /* Do final certificate and key option processing (first file only). */ 3509 rcExit2 = SigningCertKey.finalizeOptions(cVerbosity); 3510 if (rcExit2 == RTEXITCODE_SUCCESS) 3511 rcExit2 = TimestampCertKey.finalizeOptions(cVerbosity); 3512 if (rcExit2 == RTEXITCODE_SUCCESS) 2813 3513 { 2814 3514 /* Do the work: */ … … 2829 3529 rcExit = rcExit2; 2830 3530 rcExit2 = RTEXITCODE_SUCCESS; 2831 }2832 else2833 {2834 if (!TimestampCertKey.pCertificate)2835 RTMsgError("No signing certificate was specified");2836 if (TimestampCertKey.hPrivateKey == NIL_RTCRKEY)2837 RTMsgError("No signing private key was specified");2838 2839 if (!TimestampCertKey.pCertificate && !TimestampCertKey.isNull())2840 RTMsgError("No timestamp certificate was specified");2841 if (TimestampCertKey.hPrivateKey == NIL_RTCRKEY && !TimestampCertKey.isNull())2842 RTMsgError("No timestamp private key was specified");2843 rcExit2 = RTEXITCODE_SYNTAX;2844 3531 } 2845 3532 break;
Note:
See TracChangeset
for help on using the changeset viewer.