/* Generate a private/public keypair. */ OSStatus SecKeyGeneratePair(CFDictionaryRef parameters, SecKeyRef *publicKey, SecKeyRef *privateKey) { OSStatus result = errSecUnsupportedAlgorithm; SecKeyRef privKey = NULL; SecKeyRef pubKey = NULL; CFMutableDictionaryRef pubParams = merge_params(parameters, kSecPublicKeyAttrs), privParams = merge_params(parameters, kSecPrivateKeyAttrs); CFStringRef ktype = CFDictionaryGetValue(parameters, kSecAttrKeyType); require(ktype, errOut); if (CFEqual(ktype, kSecAttrKeyTypeEC)) { result = SecECKeyGeneratePair(parameters, &pubKey, &privKey); } else if (CFEqual(ktype, kSecAttrKeyTypeRSA)) { result = SecRSAKeyGeneratePair(parameters, &pubKey, &privKey); } require_noerr(result, errOut); /* Store the keys in the keychain if they are marked as permanent. */ if (getBoolForKey(pubParams, kSecAttrIsPermanent, false)) { require_noerr_quiet(result = add_ref(pubKey, pubParams), errOut); } if (getBoolForKey(privParams, kSecAttrIsPermanent, false)) { require_noerr_quiet(result = add_ref(privKey, privParams), errOut); } if (publicKey) { *publicKey = pubKey; pubKey = NULL; } if (privateKey) { *privateKey = privKey; privKey = NULL; } errOut: CFReleaseSafe(pubParams); CFReleaseSafe(privParams); CFReleaseSafe(pubKey); CFReleaseSafe(privKey); return result; }
static char * sign_hmac (OAuthProxy *proxy, RestProxyCall *call, GHashTable *oauth_params) { OAuthProxyPrivate *priv; RestProxyCallPrivate *callpriv; char *key, *signature, *ep, *eep; GString *text; GHashTable *all_params; priv = PROXY_GET_PRIVATE (proxy); callpriv = call->priv; text = g_string_new (NULL); g_string_append (text, rest_proxy_call_get_method (REST_PROXY_CALL (call))); g_string_append_c (text, '&'); if (priv->oauth_echo) { g_string_append_uri_escaped (text, priv->service_url, NULL, FALSE); } else if (priv->signature_host != NULL) { SoupURI *url = soup_uri_new (callpriv->url); gchar *signing_url; soup_uri_set_host (url, priv->signature_host); signing_url = soup_uri_to_string (url, FALSE); g_string_append_uri_escaped (text, signing_url, NULL, FALSE); soup_uri_free (url); g_free (signing_url); } else { g_string_append_uri_escaped (text, callpriv->url, NULL, FALSE); } g_string_append_c (text, '&'); /* Merge the OAuth parameters with the query parameters */ all_params = g_hash_table_new (g_str_hash, g_str_equal); merge_hashes (all_params, oauth_params); if (!priv->oauth_echo) merge_params (all_params, callpriv->params); ep = encode_params (all_params); eep = OAUTH_ENCODE_STRING (ep); g_string_append (text, eep); g_free (ep); g_free (eep); g_hash_table_destroy (all_params); /* PLAINTEXT signature value is the HMAC-SHA1 key value */ key = sign_plaintext (priv); signature = hmac_sha1 (key, text->str); g_free (key); g_string_free (text, TRUE); return signature; }