lib/krb5_wrap: add smb_krb5_create_key_from_string().
authorGünther Deschner <gd@samba.org>
Fri, 25 Apr 2014 12:12:05 +0000 (14:12 +0200)
committerAndrew Bartlett <abartlet@samba.org>
Fri, 8 Aug 2014 04:02:34 +0000 (06:02 +0200)
This function can take either a calculated salt or a principal and calculate the
salt on its own.

Guenther

Signed-off-by: Günther Deschner <gd@samba.org>
Reviewed-by: Andrew Bartlett <abartlet@samba.org>
Pair-Programmed-With: Andreas Schneider <asn@samba.org>

lib/krb5_wrap/krb5_samba.c
lib/krb5_wrap/krb5_samba.h

index ea6b7158ec64e27ca72902f9c53805f8374e6b40..b668716d8e0233ad6d022ed74dc4c2b03d2d09ac 100644 (file)
@@ -134,6 +134,78 @@ bool setup_kaddr( krb5_address *pkaddr, struct sockaddr_storage *paddr)
 #error UNKNOWN_ADDRTYPE
 #endif
 
+/**
+* @brief Create a keyblock based on input parameters
+*
+* @param context       The krb5_context
+* @param host_princ    The krb5_principal to use
+* @param salt          The optional salt, if ommitted, salt is calculated with
+*                      the provided principal.
+* @param password      The krb5_data containing the password
+* @param enctype       The krb5_enctype to use for the keyblock generation
+* @param key           The returned krb5_keyblock, caller needs to free with
+*                      krb5_free_keyblock().
+*
+* @return krb5_error_code
+*/
+int smb_krb5_create_key_from_string(krb5_context context,
+                                   krb5_principal *host_princ,
+                                   krb5_data *salt,
+                                   krb5_data *password,
+                                   krb5_enctype enctype,
+                                   krb5_keyblock *key)
+{
+       int ret = 0;
+
+       if (host_princ == NULL && salt == NULL) {
+               return -1;
+       }
+
+#if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_C_STRING_TO_KEY)
+{/* MIT */
+       krb5_data _salt;
+
+       if (salt == NULL) {
+               ret = krb5_principal2salt(context, *host_princ, &_salt);
+               if (ret) {
+                       DEBUG(1,("krb5_principal2salt failed (%s)\n", error_message(ret)));
+                       return ret;
+               }
+       } else {
+               _salt = *salt;
+       }
+       ret = krb5_c_string_to_key(context, enctype, password, &_salt, key);
+       if (salt == NULL) {
+               SAFE_FREE(_salt.data);
+       }
+}
+#elif defined(HAVE_KRB5_GET_PW_SALT) && defined(HAVE_KRB5_STRING_TO_KEY_SALT)
+{/* Heimdal */
+       krb5_salt _salt;
+
+       if (salt == NULL) {
+               ret = krb5_get_pw_salt(context, *host_princ, &_salt);
+               if (ret) {
+                       DEBUG(1,("krb5_get_pw_salt failed (%s)\n", error_message(ret)));
+                       return ret;
+               }
+       } else {
+               _salt.saltvalue = *salt;
+               _salt.salttype = KRB5_PW_SALT;
+       }
+
+       ret = krb5_string_to_key_salt(context, enctype, (const char *)password->data, _salt, key);
+       if (salt == NULL) {
+               krb5_free_salt(context, _salt);
+       }
+}
+#else
+#error UNKNOWN_CREATE_KEY_FUNCTIONS
+#endif
+       return ret;
+}
+
+
 #if defined(HAVE_KRB5_PRINCIPAL2SALT) && defined(HAVE_KRB5_C_STRING_TO_KEY)
 /* MIT */
 int create_kerberos_key_from_string_direct(krb5_context context,
index b71eebef0242182a878b07cbc1c3f2ac1b55c4cc..0c30ca898d32e667bcbf5b1f3523704d5b46147c 100644 (file)
@@ -304,6 +304,13 @@ int smb_krb5_get_pw_salt(krb5_context context,
                         krb5_principal host_princ,
                         krb5_data *psalt);
 
+int smb_krb5_create_key_from_string(krb5_context context,
+                                   krb5_principal *host_princ,
+                                   krb5_data *salt,
+                                   krb5_data *password,
+                                   krb5_enctype enctype,
+                                   krb5_keyblock *key);
+
 #endif /* HAVE_KRB5 */
 
 int cli_krb5_get_ticket(TALLOC_CTX *mem_ctx,