1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 */ 21 /* 22 * Copyright 2007 Sun Microsystems, Inc. All rights reserved. 23 * Use is subject to license terms. 24 */ 25 26 #pragma ident "%Z%%M% %I% %E% SMI" 27 28 #include <stdio.h> 29 #include <link.h> 30 #include <fcntl.h> 31 #include <ctype.h> 32 #include <sys/param.h> 33 #include <sys/types.h> 34 #include <sys/stat.h> 35 #include <ber_der.h> 36 #include <kmfapiP.h> 37 #include <libgen.h> 38 #include <cryptoutil.h> 39 40 /* 41 * 42 * Name: KMF_SignDataWithKey 43 * 44 * Description: 45 * This function signs a block of data using the private key 46 * and returns the signature in output 47 * 48 * Parameters: 49 * handle(input) - opaque handle for KMF session 50 * key(input) - contains private key handle needed for signing 51 * AlgOID(input) - contains algorithm to be used for signing 52 * tobesigned(input) - pointer to a KMF_DATA structure containing 53 * the data to be signed 54 * output(output) - pointer to the KMF_DATA structure containing the 55 * signed data 56 * 57 * Returns: 58 * A KMF_RETURN value indicating success or specifying a particular 59 * error condition. 60 * The value KMF_OK indicates success. All other values represent 61 * an error condition. 62 * 63 */ 64 KMF_RETURN 65 KMF_SignDataWithKey(KMF_HANDLE_T handle, 66 KMF_KEY_HANDLE *key, 67 KMF_OID *AlgOID, 68 KMF_DATA *tobesigned, 69 KMF_DATA *output) 70 { 71 KMF_RETURN ret; 72 KMF_PLUGIN *plugin; 73 KMF_ALGORITHM_INDEX AlgId; 74 KMF_DATA signature = {0, NULL}; 75 76 CLEAR_ERROR(handle, ret); 77 if (ret != KMF_OK) 78 return (ret); 79 80 if (key == NULL || AlgOID == NULL || 81 tobesigned == NULL || output == NULL) 82 return (KMF_ERR_BAD_PARAMETER); 83 84 /* 85 * The plugin must be based on the key since private keys 86 * cannot be extracted. 87 */ 88 plugin = FindPlugin(handle, key->kstype); 89 if (plugin != NULL && plugin->funclist->SignData != NULL) { 90 ret = plugin->funclist->SignData(handle, key, 91 AlgOID, tobesigned, output); 92 if (ret != KMF_OK) 93 goto cleanup; 94 95 AlgId = X509_AlgorithmOidToAlgId(AlgOID); 96 97 /* 98 * For DSA, NSS returns an encoded signature. Decode the 99 * signature as DSA signature should be 40-byte long. 100 */ 101 if ((AlgId == KMF_ALGID_SHA1WithDSA) && 102 (plugin->type == KMF_KEYSTORE_NSS)) { 103 ret = DerDecodeDSASignature(output, &signature); 104 if (ret != KMF_OK) { 105 goto cleanup; 106 } else { 107 output->Length = signature.Length; 108 (void) memcpy(output->Data, signature.Data, 109 signature.Length); 110 } 111 } else if (AlgId == KMF_ALGID_NONE) { 112 ret = KMF_ERR_BAD_ALGORITHM; 113 } 114 } else { 115 return (KMF_ERR_PLUGIN_NOTFOUND); 116 } 117 118 cleanup: 119 if (signature.Data) 120 free(signature.Data); 121 return (ret); 122 } 123 124 /* 125 * 126 * Name: KMF_VerifyDataWithKey 127 * 128 * Description: 129 * This function verifies the signature of a block of data 130 * using the input public key 131 * 132 * Parameters: 133 * handle(input) - opaque handle for KMF session 134 * KMFKey(input) - holds public key information for verification 135 * sigAlg(input) - algorithm to verify 136 * indata(input) - pointer to the block of data whose signature 137 * is to be verified 138 * insig(input) - pointer to the signature to be verified 139 * 140 * Returns: 141 * A KMF_RETURN value indicating success or specifying a particular 142 * error condition. 143 * The value KMF_OK indicates success. All other values represent 144 * an error condition. 145 * 146 */ 147 KMF_RETURN 148 KMF_VerifyDataWithKey(KMF_HANDLE_T handle, 149 KMF_KEY_HANDLE *KMFKey, 150 KMF_ALGORITHM_INDEX sigAlg, 151 KMF_DATA *indata, 152 KMF_DATA *insig) 153 { 154 KMF_RETURN err; 155 KMF_DATA derkey = {0, NULL}; 156 KMF_PLUGIN *plugin; 157 158 CLEAR_ERROR(handle, err); 159 if (err != KMF_OK) 160 return (err); 161 162 if (KMFKey == NULL || 163 indata == NULL || insig == NULL) 164 return (KMF_ERR_BAD_PARAMETER); 165 166 plugin = FindPlugin(handle, KMFKey->kstype); 167 168 /* Retrieve public key data from keystore */ 169 if (plugin != NULL && plugin->funclist->EncodePubkeyData != NULL) { 170 err = plugin->funclist->EncodePubkeyData(handle, 171 KMFKey, &derkey); 172 } else { 173 return (KMF_ERR_PLUGIN_NOTFOUND); 174 } 175 176 err = VerifyDataWithKey(handle, &derkey, sigAlg, indata, insig); 177 178 if (derkey.Data != NULL) 179 free(derkey.Data); 180 181 return (err); 182 } 183 184 KMF_RETURN 185 KMF_CreateKeypair(KMF_HANDLE_T handle, 186 KMF_CREATEKEYPAIR_PARAMS *params, 187 KMF_KEY_HANDLE *privKey, 188 KMF_KEY_HANDLE *pubKey) 189 { 190 KMF_PLUGIN *plugin; 191 KMF_RETURN ret; 192 193 CLEAR_ERROR(handle, ret); 194 if (ret != KMF_OK) 195 return (ret); 196 197 if (params == NULL || 198 privKey == NULL || pubKey == NULL) 199 return (KMF_ERR_BAD_PARAMETER); 200 201 (void) memset(privKey, 0, sizeof (KMF_KEY_HANDLE)); 202 (void) memset(pubKey, 0, sizeof (KMF_KEY_HANDLE)); 203 plugin = FindPlugin(handle, params->kstype); 204 205 if (plugin != NULL && plugin->funclist->CreateKeypair != NULL) { 206 return (plugin->funclist->CreateKeypair(handle, params, 207 privKey, pubKey)); 208 } else { 209 return (KMF_ERR_PLUGIN_NOTFOUND); 210 } 211 } 212 213 KMF_RETURN 214 KMF_DeleteKeyFromKeystore(KMF_HANDLE_T handle, KMF_DELETEKEY_PARAMS *params, 215 KMF_KEY_HANDLE *key) 216 { 217 KMF_RETURN rv = KMF_OK; 218 KMF_PLUGIN *plugin; 219 220 CLEAR_ERROR(handle, rv); 221 if (rv != KMF_OK) 222 return (rv); 223 224 if (key == NULL || params == NULL) 225 return (KMF_ERR_BAD_PARAMETER); 226 227 plugin = FindPlugin(handle, params->kstype); 228 if (plugin != NULL && plugin->funclist->DeleteKey != NULL) { 229 rv = plugin->funclist->DeleteKey(handle, params, key, TRUE); 230 } else { 231 rv = KMF_ERR_PLUGIN_NOTFOUND; 232 } 233 234 if (rv == KMF_OK) { 235 if (key->keylabel != NULL) 236 free(key->keylabel); 237 238 if (key->israw && key->keyp != NULL) { 239 if (key->keyclass == KMF_ASYM_PUB || 240 key->keyclass == KMF_ASYM_PRI) { 241 KMF_FreeRawKey(key->keyp); 242 free(key->keyp); 243 } else if (key->keyclass == KMF_SYMMETRIC) { 244 KMF_FreeRawSymKey(key->keyp); 245 } 246 /* Else we don't know how to free the memory. */ 247 } 248 249 (void) memset(key, 0, sizeof (KMF_KEY_HANDLE)); 250 } 251 252 return (rv); 253 } 254 255 KMF_RETURN 256 KMF_SignCertRecord(KMF_HANDLE_T handle, KMF_KEY_HANDLE *kmfprikey, 257 KMF_X509_CERTIFICATE *CertData, KMF_DATA *signedCert) 258 { 259 KMF_RETURN ret; 260 KMF_DATA unsignedCert; 261 262 CLEAR_ERROR(handle, ret); 263 if (ret != KMF_OK) 264 return (ret); 265 266 if (kmfprikey == NULL || 267 CertData == NULL || signedCert == NULL) 268 return (KMF_ERR_BAD_PARAMETER); 269 270 ret = KMF_EncodeCertRecord(CertData, &unsignedCert); 271 if (ret == KMF_OK) 272 ret = KMF_SignCertWithKey(handle, &unsignedCert, kmfprikey, 273 signedCert); 274 275 KMF_FreeData(&unsignedCert); 276 return (ret); 277 } 278 279 KMF_RETURN 280 KMF_FindKey(KMF_HANDLE_T handle, KMF_FINDKEY_PARAMS *parms, 281 KMF_KEY_HANDLE *keys, uint32_t *numkeys) 282 { 283 KMF_PLUGIN *plugin; 284 KMF_RETURN ret; 285 286 CLEAR_ERROR(handle, ret); 287 if (ret != KMF_OK) 288 return (ret); 289 290 if (parms == NULL || numkeys == NULL) 291 return (KMF_ERR_BAD_PARAMETER); 292 293 plugin = FindPlugin(handle, parms->kstype); 294 295 if (plugin != NULL && plugin->funclist->FindKey != NULL) { 296 return (plugin->funclist->FindKey(handle, parms, 297 keys, numkeys)); 298 } 299 300 return (KMF_ERR_PLUGIN_NOTFOUND); 301 } 302 303 KMF_RETURN 304 KMF_StorePrivateKey(KMF_HANDLE_T handle, KMF_STOREKEY_PARAMS *params, 305 KMF_RAW_KEY_DATA *rawkey) 306 { 307 KMF_PLUGIN *plugin; 308 KMF_RETURN ret; 309 310 CLEAR_ERROR(handle, ret); 311 if (ret != KMF_OK) 312 return (ret); 313 314 if (params == NULL || rawkey == NULL) 315 return (KMF_ERR_BAD_PARAMETER); 316 317 /* Find the private key from the keystore */ 318 plugin = FindPlugin(handle, params->kstype); 319 320 if (plugin != NULL && plugin->funclist->StorePrivateKey != NULL) { 321 return (plugin->funclist->StorePrivateKey(handle, 322 params, rawkey)); 323 } 324 return (KMF_ERR_PLUGIN_NOTFOUND); 325 } 326 327 KMF_RETURN 328 KMF_CreateSymKey(KMF_HANDLE_T handle, KMF_CREATESYMKEY_PARAMS *params, 329 KMF_KEY_HANDLE *symkey) 330 { 331 KMF_PLUGIN *plugin; 332 KMF_RETURN ret; 333 334 CLEAR_ERROR(handle, ret); 335 if (ret != KMF_OK) 336 return (ret); 337 338 if (params == NULL || 339 symkey == NULL) 340 return (KMF_ERR_BAD_PARAMETER); 341 342 plugin = FindPlugin(handle, params->kstype); 343 if (plugin != NULL && plugin->funclist->CreateSymKey != NULL) { 344 return (plugin->funclist->CreateSymKey(handle, params, 345 symkey)); 346 } else { 347 return (KMF_ERR_PLUGIN_NOTFOUND); 348 } 349 } 350 351 KMF_RETURN 352 KMF_GetSymKeyValue(KMF_HANDLE_T handle, KMF_KEY_HANDLE *symkey, 353 KMF_RAW_SYM_KEY *rkey) 354 { 355 KMF_PLUGIN *plugin; 356 KMF_RETURN ret; 357 358 CLEAR_ERROR(handle, ret); 359 if (ret != KMF_OK) 360 return (ret); 361 362 if (symkey == NULL || rkey == NULL) 363 return (KMF_ERR_BAD_PARAMETER); 364 365 plugin = FindPlugin(handle, symkey->kstype); 366 if (plugin != NULL && 367 plugin->funclist->GetSymKeyValue != NULL) { 368 return (plugin->funclist->GetSymKeyValue(handle, 369 symkey, rkey)); 370 } else { 371 return (KMF_ERR_PLUGIN_NOTFOUND); 372 } 373 } 374