comparison cinst/windowsstore.c @ 222:53ea9b975d1c

Cleanup windowsstore.c The cause for the test failure was that ADD_ALWAYS did not add a duplicate in the Root store but did add a duplicate in the Memory Store. We now check if the certificate is already in the store before actually installing it.
author Andre Heinecke <aheinecke@intevation.de>
date Thu, 27 Mar 2014 14:16:22 +0000
parents 57bef180d560
children 4de97f74d038
comparison
equal deleted inserted replaced
221:431b058e903d 222:53ea9b975d1c
5 #include "windowsstore.h" 5 #include "windowsstore.h"
6 #include "errorcodes.h" 6 #include "errorcodes.h"
7 #include "listutil.h" 7 #include "listutil.h"
8 #include "strhelp.h" 8 #include "strhelp.h"
9 9
10 static LPWSTR getLastErrorMsg() 10 static LPWSTR
11 getLastErrorMsg()
11 { 12 {
12 LPWSTR bufPtr = NULL; 13 LPWSTR bufPtr = NULL;
13 DWORD err = GetLastError(); 14 DWORD err = GetLastError();
14 FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER | 15 FormatMessageW (FORMAT_MESSAGE_ALLOCATE_BUFFER |
15 FORMAT_MESSAGE_FROM_SYSTEM | 16 FORMAT_MESSAGE_FROM_SYSTEM |
30 if (!bufPtr) 31 if (!bufPtr)
31 printf ("Error getting last error for code: %lx \n", err); 32 printf ("Error getting last error for code: %lx \n", err);
32 return bufPtr; 33 return bufPtr;
33 } 34 }
34 35
36 static PCCERT_CONTEXT
37 b64_to_cert_context(char *b64_data, size_t b64_size)
38 {
39 size_t buf_size = 0;
40 char *buf = NULL;
41 PCCERT_CONTEXT pCert = NULL;
42 int ret = -1;
43
44 ret = str_base64_decode (&buf, &buf_size, b64_data, b64_size);
45
46 if (ret != 0)
47 {
48 printf ("decoding certificate failed\n");
49 return NULL;
50 }
51
52 pCert = CertCreateContext (CERT_STORE_CERTIFICATE_CONTEXT,
53 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
54 (const PBYTE) buf,
55 (DWORD) buf_size,
56 0,
57 NULL);
58 free (buf); /* Windows has a copy */
59
60 if (pCert == NULL)
61 {
62 LPWSTR error = getLastErrorMsg();
63 if (error)
64 {
65 printf ("Failed to create cert context: %S \n", error);
66 LocalFree (error);
67 }
68 return NULL;
69 }
70 return pCert;
71 }
72
35 void 73 void
36 do_remove(HCERTSTORE hStore, char **to_remove) 74 do_remove(HCERTSTORE hStore, char **to_remove)
37 { 75 {
38 PCCERT_CONTEXT pCert = NULL; 76 PCCERT_CONTEXT pCert = NULL;
39 unsigned int i = 0; 77 unsigned int i = 0;
43 return; 81 return;
44 } 82 }
45 83
46 for (i=0; to_remove[i]; i++) 84 for (i=0; to_remove[i]; i++)
47 { 85 {
48 char *asn1_data = NULL;
49 size_t asn1_size = 0;
50 int ret = -1;
51 DWORD j;
52 PCCERT_CONTEXT pc_to_remove = NULL; 86 PCCERT_CONTEXT pc_to_remove = NULL;
53 87
54 ret = str_base64_decode (&asn1_data, &asn1_size, to_remove[i], 88 pc_to_remove = b64_to_cert_context(to_remove[i],
55 strnlen(to_remove[i], MAX_LINE_LENGTH)); 89 strnlen(to_remove[i], MAX_LINE_LENGTH));
56 /* Decoding / parsing errors in here should not happen at all. 90
57 The only errors which are not a bug would be out of memory or
58 if the signed certificate list contained an invalid certificate. */
59 if (ret != 0)
60 {
61 printf ("Error base64 certificate.\n");
62 continue;
63 }
64
65 printf ("Deleting cert %s\n", to_remove[i]);
66 pc_to_remove = CertCreateContext (CERT_STORE_CERTIFICATE_CONTEXT,
67 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
68 (const PBYTE) asn1_data,
69 (DWORD) asn1_size,
70 0,
71 NULL);
72 free (asn1_data); /* Windows has a copy */
73 if (pc_to_remove == NULL) 91 if (pc_to_remove == NULL)
74 { 92 {
75 LPWSTR error = getLastErrorMsg(); 93 LPWSTR error = getLastErrorMsg();
76 if (error) 94 if (error)
77 { 95 {
78 printf ("Failed to add certificate: %S \n", error); 96 printf ("Failed to create cert context: %S \n", error);
79 LocalFree (error); 97 LocalFree (error);
80 } 98 }
81 continue; 99 continue;
82 } 100 }
83 101
86 0, 104 0,
87 CERT_FIND_EXISTING, 105 CERT_FIND_EXISTING,
88 pc_to_remove, 106 pc_to_remove,
89 NULL); 107 NULL);
90 108
91
92 {
93 char pszNameString[256];
94 if(CertGetNameString(
95 pc_to_remove,
96 CERT_NAME_SIMPLE_DISPLAY_TYPE,
97 0,
98 NULL,
99 pszNameString,
100 128))
101 {
102 printf("wanted: %s \n",pszNameString);
103 }
104 if(CertGetNameString(
105 pCert,
106 CERT_NAME_SIMPLE_DISPLAY_TYPE,
107 0,
108 NULL,
109 pszNameString,
110 128))
111 {
112 printf("got: %s \n",pszNameString);
113 }
114 }
115
116 CertFreeCertificateContext (pc_to_remove); 109 CertFreeCertificateContext (pc_to_remove);
117 110
118 if (pCert == NULL) 111 if (pCert == NULL)
119 { 112 {
120 printf ("Did not find certificate\n"); 113 printf ("Did not find certificate\n");
121 continue; 114 continue;
122 } 115 }
123 for (j = 0; j < pCert->cbCertEncoded; j++) {
124 if (asn1_data[j] != pCert->pbCertEncoded[j]) {
125 printf("%1x", (unsigned)(unsigned char)pCert->pbCertEncoded[j]);
126 }
127 }
128 printf("\nWanted: \n");
129 for (j = 0; j < pCert->cbCertEncoded; j++) {
130 if (asn1_data[j] != pCert->pbCertEncoded[j]) {
131 printf("%1x", (unsigned)(unsigned char)asn1_data[j]);
132 }
133 }
134 printf("\n");
135 116
136 if (!CertDeleteCertificateFromStore (pCert)) 117 if (!CertDeleteCertificateFromStore (pCert))
137 { 118 {
138 /* From MSDN: 119 /* From MSDN:
139 The CertDeleteCertificateFromStore function always frees 120 The CertDeleteCertificateFromStore function always frees
159 return; 140 return;
160 } 141 }
161 142
162 for (i = 0; to_install[i]; i++) 143 for (i = 0; to_install[i]; i++)
163 { 144 {
164 size_t cert_len = strnlen (to_install[i], MAX_LINE_LENGTH), 145 PCCERT_CONTEXT pc_to_add = NULL;
165 buf_size = 0; 146 PCCERT_CONTEXT found_cert = NULL;
166 char *buf = NULL; 147
167 148 pc_to_add = b64_to_cert_context(to_install[i],
168 ret = str_base64_decode (&buf, &buf_size, to_install[i], cert_len); 149 strnlen(to_install[i], MAX_LINE_LENGTH));
169 150
170 if (ret != 0) 151 if (pc_to_add == NULL)
171 { 152 {
172 printf ("decoding certificate failed\n"); 153 continue;
173 return; 154 }
174 } 155
175 156 found_cert = CertFindCertificateInStore (hStore,
176 printf ("Adding cert %s\n", to_install[i]); 157 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING,
177 158 0,
178 ret = CertAddEncodedCertificateToStore (hStore, 159 CERT_FIND_EXISTING,
179 X509_ASN_ENCODING | PKCS_7_ASN_ENCODING, 160 pc_to_add,
180 (PBYTE) buf, 161 NULL);
181 buf_size, 162 if (found_cert != NULL)
163 {
164 printf ("Certificate already in store\n");
165 CertFreeCertificateContext (found_cert);
166 CertFreeCertificateContext (pc_to_add);
167 continue;
168 }
169
170 ret = CertAddCertificateContextToStore (hStore,
171 pc_to_add,
182 CERT_STORE_ADD_ALWAYS, 172 CERT_STORE_ADD_ALWAYS,
183 NULL); 173 NULL);
184 174 CertFreeCertificateContext (pc_to_add);
185 if (!ret) 175 if (!ret)
186 { 176 {
187 LPWSTR error = getLastErrorMsg(); 177 LPWSTR error = getLastErrorMsg();
188 if (error) 178 if (error)
189 { 179 {
190 printf ("Failed to add certificate: %S \n", error); 180 printf ("Failed to add certificate: %S \n", error);
191 LocalFree (error); 181 LocalFree (error);
192 } 182 }
193 } 183 }
194 free (buf);
195 } 184 }
196 return; 185 return;
197 } 186 }
198 187
199 int 188 int

http://wald.intevation.org/projects/trustbridge/