2 * Copyright (c) 2011, JANET(UK)
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
9 * 1. Redistributions of source code must retain the above copyright
10 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
16 * 3. Neither the name of JANET(UK) nor the names of its contributors
17 * may be used to endorse or promote products derived from this software
18 * without specific prior written permission.
20 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21 * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23 * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
24 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
25 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
26 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
27 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
28 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
29 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
33 #include "gssapiP_eap.h"
35 #ifdef HAVE_MOONSHOT_GET_IDENTITY
36 #include <libmoonshot.h>
39 libMoonshotMapError(OM_uint32 *minor,
40 MoonshotError **pError)
42 MoonshotError *error = *pError;
44 GSSEAP_ASSERT(error != NULL);
46 switch (error->code) {
47 case MOONSHOT_ERROR_UNABLE_TO_START_SERVICE:
48 *minor = GSSEAP_UNABLE_TO_START_IDENTITY_SERVICE;
50 case MOONSHOT_ERROR_NO_IDENTITY_SELECTED:
51 *minor = GSSEAP_NO_IDENTITY_SELECTED;
53 case MOONSHOT_ERROR_INSTALLATION_ERROR:
54 *minor = GSSEAP_IDENTITY_SERVICE_INSTALL_ERROR;
56 case MOONSHOT_ERROR_OS_ERROR:
57 *minor = GSSEAP_IDENTITY_SERVICE_OS_ERROR;
59 case MOONSHOT_ERROR_IPC_ERROR:
60 *minor = GSSEAP_IDENTITY_SERVICE_IPC_ERROR;
63 *minor = GSSEAP_IDENTITY_SERVICE_UNKNOWN_ERROR;
67 gssEapSaveStatusInfo(*minor, error->message);
68 moonshot_error_free(error);
71 return GSS_S_CRED_UNAVAIL;
75 libMoonshotResolveDefaultIdentity(OM_uint32 *minor,
76 const gss_cred_id_t cred,
79 OM_uint32 major, tmpMinor;
80 gss_OID nameMech = gssEapPrimaryMechForCred(cred);
81 gss_name_t name = GSS_C_NO_NAME;
82 gss_buffer_desc tmpBuffer = GSS_C_EMPTY_BUFFER;
84 char *password = NULL;
85 char *serverCertificateHash = NULL;
86 char *caCertificate = NULL;
87 char *subjectNameConstraint = NULL;
88 char *subjectAltNameConstraint = NULL;
89 MoonshotError *error = NULL;
91 *pName = GSS_C_NO_NAME;
93 if (!moonshot_get_default_identity(&nai,
95 &serverCertificateHash,
97 &subjectNameConstraint,
98 &subjectAltNameConstraint,
100 if (error->code == MOONSHOT_ERROR_NO_IDENTITY_SELECTED) {
101 major = GSS_S_CRED_UNAVAIL;
102 *minor = GSSEAP_NO_DEFAULT_IDENTITY;
103 moonshot_error_free(error);
105 major = libMoonshotMapError(minor, &error);
109 tmpBuffer.value = nai;
110 tmpBuffer.length = strlen(nai);
112 major = gssEapImportName(minor, &tmpBuffer, GSS_C_NT_USER_NAME, nameMech, &name);
113 if (GSS_ERROR(major))
117 name = GSS_C_NO_NAME;
121 moonshot_free(password);
122 moonshot_free(serverCertificateHash);
123 moonshot_free(caCertificate);
124 moonshot_free(subjectNameConstraint);
125 moonshot_free(subjectAltNameConstraint);
127 gssEapReleaseName(&tmpMinor, &name);
132 static int stringEmpty(const char * s)
142 libMoonshotResolveInitiatorCred(OM_uint32 *minor,
144 gss_const_name_t targetName)
146 OM_uint32 major, tmpMinor;
147 gss_OID nameMech = gssEapPrimaryMechForCred(cred);
148 gss_buffer_desc initiator = GSS_C_EMPTY_BUFFER;
149 gss_buffer_desc target = GSS_C_EMPTY_BUFFER;
150 gss_buffer_desc tmpBuffer = GSS_C_EMPTY_BUFFER;
152 char *password = NULL;
153 char *serverCertificateHash = NULL;
154 char *caCertificate = NULL;
155 char *subjectNameConstraint = NULL;
156 char *subjectAltNameConstraint = NULL;
157 MoonshotError *error = NULL;
159 if (cred->name != GSS_C_NO_NAME) {
160 major = gssEapDisplayName(minor, cred->name, &initiator, NULL);
161 if (GSS_ERROR(major))
165 if (targetName != GSS_C_NO_NAME) {
166 major = gssEapDisplayName(minor, targetName, &target, NULL);
167 if (GSS_ERROR(major))
171 if (!moonshot_get_identity((const char *)initiator.value,
172 (const char *)cred->password.value,
173 (const char *)target.value,
176 &serverCertificateHash,
178 &subjectNameConstraint,
179 &subjectAltNameConstraint,
181 major = libMoonshotMapError(minor, &error);
185 gssEapReleaseName(&tmpMinor, &cred->name);
187 tmpBuffer.value = nai;
188 tmpBuffer.length = strlen(nai);
190 major = gssEapImportName(minor, &tmpBuffer, GSS_C_NT_USER_NAME,
191 nameMech, &cred->name);
192 if (GSS_ERROR(major))
195 tmpBuffer.value = password;
196 tmpBuffer.length = strlen(password);
198 major = gssEapSetCredPassword(minor, cred, &tmpBuffer);
199 if (GSS_ERROR(major))
202 gss_release_buffer(&tmpMinor, &cred->caCertificate);
203 gss_release_buffer(&tmpMinor, &cred->caCertificateBlob);
204 gss_release_buffer(&tmpMinor, &cred->subjectNameConstraint);
205 gss_release_buffer(&tmpMinor, &cred->subjectAltNameConstraint);
207 if (!stringEmpty(serverCertificateHash)) {
208 size_t len = strlen(serverCertificateHash);
210 #define HASH_PREFIX "hash://server/sha256/"
211 #define HASH_PREFIX_LEN (sizeof(HASH_PREFIX) - 1)
213 cred->caCertificate.value = GSSEAP_MALLOC(HASH_PREFIX_LEN + len + 1);
214 if (cred->caCertificate.value == NULL) {
215 major = GSS_S_FAILURE;
220 memcpy(cred->caCertificate.value, HASH_PREFIX, HASH_PREFIX_LEN);
221 memcpy((char *)cred->caCertificate.value + HASH_PREFIX_LEN, serverCertificateHash, len);
223 ((char *)cred->caCertificate.value)[HASH_PREFIX_LEN + len] = '\0';
225 cred->caCertificate.length = HASH_PREFIX_LEN + len;
226 } else if (!stringEmpty(caCertificate)) {
229 ssize_t maxLength = ((strlen(caCertificate) + 3) / 4) * 3;
231 major = GSS_S_FAILURE;
232 *minor = GSSEAP_BAD_CACERTIFICATE;
235 blobData = GSSEAP_MALLOC(maxLength);
236 if (blobData == NULL) {
237 major = GSS_S_FAILURE;
242 blobLength = base64Decode(caCertificate, blobData);
244 if (blobLength <= 0) {
245 major = GSS_S_DEFECTIVE_CREDENTIAL;
246 *minor = GSSEAP_BAD_CACERTIFICATE;
247 GSSEAP_FREE(blobData);
250 cred->caCertificateBlob.value = blobData;
251 cred->caCertificateBlob.length = blobLength;
252 makeStringBufferOrCleanup("blob://ca-cert", &cred->caCertificate);
255 if (!stringEmpty(subjectNameConstraint))
256 makeStringBufferOrCleanup(subjectNameConstraint, &cred->subjectNameConstraint);
257 if (!stringEmpty(subjectAltNameConstraint))
258 makeStringBufferOrCleanup(subjectAltNameConstraint, &cred->subjectAltNameConstraint);
262 moonshot_free(password);
263 moonshot_free(serverCertificateHash);
264 moonshot_free(caCertificate);
265 moonshot_free(subjectNameConstraint);
266 moonshot_free(subjectAltNameConstraint);
268 gss_release_buffer(&tmpMinor, &initiator);
269 gss_release_buffer(&tmpMinor, &target);
273 #endif /* HAVE_MOONSHOT_GET_IDENTITY */