diff options
Diffstat (limited to 'crypto/heimdal/doc/programming.texi')
-rw-r--r-- | crypto/heimdal/doc/programming.texi | 642 |
1 files changed, 0 insertions, 642 deletions
diff --git a/crypto/heimdal/doc/programming.texi b/crypto/heimdal/doc/programming.texi deleted file mode 100644 index 528348b..0000000 --- a/crypto/heimdal/doc/programming.texi +++ /dev/null @@ -1,642 +0,0 @@ -@c $Id: programming.texi 22071 2007-11-14 20:04:50Z lha $ - -@node Programming with Kerberos, Migration, Windows 2000 compatability, Top -@chapter Programming with Kerberos - -First you need to know how the Kerberos model works, go read the -introduction text (@pxref{What is Kerberos?}). - -@menu -* Kerberos 5 API Overview:: -* Walkthrough of a sample Kerberos 5 client:: -* Validating a password in a server application:: -* API differences to MIT Kerberos:: -* File formats:: -@end menu - -@node Kerberos 5 API Overview, Walkthrough of a sample Kerberos 5 client, Programming with Kerberos, Programming with Kerberos -@section Kerberos 5 API Overview - -All functions are documented in manual pages. This section tries to -give an overview of the major components used in Kerberos library, and -point to where to look for a specific function. - -@subsection Kerberos context - -A kerberos context (@code{krb5_context}) holds all per thread state. All global variables that -are context specific are stored in this structure, including default -encryption types, credential cache (for example, a ticket file), and default realms. - -See the manual pages for @manpage{krb5_context,3} and -@manpage{krb5_init_context,3}. - -@subsection Kerberos authentication context - -Kerberos authentication context (@code{krb5_auth_context}) holds all -context related to an authenticated connection, in a similar way to the -kerberos context that holds the context for the thread or process. - -The @code{krb5_auth_context} is used by various functions that are -directly related to authentication between the server/client. Example of -data that this structure contains are various flags, addresses of client -and server, port numbers, keyblocks (and subkeys), sequence numbers, -replay cache, and checksum types. - -See the manual page for @manpage{krb5_auth_context,3}. - -@subsection Kerberos principal - -The Kerberos principal is the structure that identifies a user or -service in Kerberos. The structure that holds the principal is the -@code{krb5_principal}. There are function to extract the realm and -elements of the principal, but most applications have no reason to -inspect the content of the structure. - -The are several ways to create a principal (with different degree of -portability), and one way to free it. - -See manual page for @manpage{krb5_principal,3} for more information -about the functions. - -@subsection Credential cache - -A credential cache holds the tickets for a user. A given user can have -several credential caches, one for each realm where the user have the -initial tickets (the first krbtgt). - -The credential cache data can be stored internally in different way, each of them for -different proposes. File credential (FILE) caches and processes based -(KCM) caches are for permanent storage. While memory caches (MEMORY) -are local caches to the local process. - -Caches are opened with @manpage{krb5_cc_resolve,3} or created with -@manpage{krb5_cc_gen_unique,3}. - -If the cache needs to be opened again (using -@manpage{krb5_cc_resolve,3}) @manpage{krb5_cc_close,3} will close the -handle, but not the remove the cache. @manpage{krb5_cc_destroy,3} will -zero out the cache, remove the cache so it can no longer be -referenced. - -See also manual page for @manpage{krb5_ccache,3} - -@subsection Kerberos errors - -Kerberos errors are based on the com_err library. All error codes are -32-bit signed numbers, the first 24 bits define what subsystem the -error originates from, and last 8 bits are 255 error codes within the -library. Each error code have fixed string associated with it. For -example, the error-code -1765328383 have the symbolic name -KRB5KDC_ERR_NAME_EXP, and associated error string ``Client's entry in -database has expired''. - -This is a great improvement compared to just getting one of the unix -error-codes back. However, Heimdal have an extention to pass back -customised errors messages. Instead of getting ``Key table entry not -found'', the user might back ``failed to find -host/host.example.com@@EXAMLE.COM(kvno 3) in keytab /etc/krb5.keytab -(des-cbc-crc)''. This improves the chance that the user find the -cause of the error so you should use the customised error message -whenever it's available. - -See also manual page for @manpage{krb5_get_error_string,3} and -@manpage{krb5_get_err_text,3}. - -@subsection Keytab management - -A keytab is a storage for locally stored keys. Heimdal includes keytab -support for Kerberos 5 keytabs, Kerberos 4 srvtab, AFS-KeyFile's, -and for storing keys in memory. - -Keytabs are used for servers and long-running services. - -See also manual page for @manpage{krb5_keytab,3} - -@subsection Kerberos crypto - -Heimdal includes a implementation of the Kerberos crypto framework, -all crypto operations. - -See also manual page for @manpage{krb5_crypto_init,3}, -@manpage{krb5_keyblock,3}, @manpage{krb5_create_checksum,3}, -and @manpage{krb5_encrypt,3}. - -@node Walkthrough of a sample Kerberos 5 client, Validating a password in a server application, Kerberos 5 API Overview, Programming with Kerberos -@section Walkthrough of a sample Kerberos 5 client - -This example contains parts of a sample TCP Kerberos 5 clients, if you -want a real working client, please look in @file{appl/test} directory in -the Heimdal distribution. - -All Kerberos error-codes that are returned from kerberos functions in -this program are passed to @code{krb5_err}, that will print a -descriptive text of the error code and exit. Graphical programs can -convert error-code to a human readable error-string with the -@manpage{krb5_get_err_text,3} function. - -Note that you should not use any Kerberos function before -@code{krb5_init_context()} have completed successfully. That is the -reason @code{err()} is used when @code{krb5_init_context()} fails. - -First the client needs to call @code{krb5_init_context} to initialise -the Kerberos 5 library. This is only needed once per thread -in the program. If the function returns a non-zero value it indicates -that either the Kerberos implementation is failing or it's disabled on -this host. - -@example -#include <krb5.h> - -int -main(int argc, char **argv) -@{ - krb5_context context; - - if (krb5_context(&context)) - errx (1, "krb5_context"); -@end example - -Now the client wants to connect to the host at the other end. The -preferred way of doing this is using @manpage{getaddrinfo,3} (for -operating system that have this function implemented), since getaddrinfo -is neutral to the address type and can use any protocol that is available. - -@example - struct addrinfo *ai, *a; - struct addrinfo hints; - int error; - - memset (&hints, 0, sizeof(hints)); - hints.ai_socktype = SOCK_STREAM; - hints.ai_protocol = IPPROTO_TCP; - - error = getaddrinfo (hostname, "pop3", &hints, &ai); - if (error) - errx (1, "%s: %s", hostname, gai_strerror(error)); - - for (a = ai; a != NULL; a = a->ai_next) @{ - int s; - - s = socket (a->ai_family, a->ai_socktype, a->ai_protocol); - if (s < 0) - continue; - if (connect (s, a->ai_addr, a->ai_addrlen) < 0) @{ - warn ("connect(%s)", hostname); - close (s); - continue; - @} - freeaddrinfo (ai); - ai = NULL; - @} - if (ai) @{ - freeaddrinfo (ai); - errx ("failed to contact %s", hostname); - @} -@end example - -Before authenticating, an authentication context needs to be -created. This context keeps all information for one (to be) authenticated -connection (see @manpage{krb5_auth_context,3}). - -@example - status = krb5_auth_con_init (context, &auth_context); - if (status) - krb5_err (context, 1, status, "krb5_auth_con_init"); -@end example - -For setting the address in the authentication there is a help function -@code{krb5_auth_con_setaddrs_from_fd} that does everything that is needed -when given a connected file descriptor to the socket. - -@example - status = krb5_auth_con_setaddrs_from_fd (context, - auth_context, - &sock); - if (status) - krb5_err (context, 1, status, - "krb5_auth_con_setaddrs_from_fd"); -@end example - -The next step is to build a server principal for the service we want -to connect to. (See also @manpage{krb5_sname_to_principal,3}.) - -@example - status = krb5_sname_to_principal (context, - hostname, - service, - KRB5_NT_SRV_HST, - &server); - if (status) - krb5_err (context, 1, status, "krb5_sname_to_principal"); -@end example - -The client principal is not passed to @manpage{krb5_sendauth,3} -function, this causes the @code{krb5_sendauth} function to try to figure it -out itself. - -The server program is using the function @manpage{krb5_recvauth,3} to -receive the Kerberos 5 authenticator. - -In this case, mutual authentication will be tried. That means that the server -will authenticate to the client. Using mutual authentication -is good since it enables the user to verify that they are talking to the -right server (a server that knows the key). - -If you are using a non-blocking socket you will need to do all work of -@code{krb5_sendauth} yourself. Basically you need to send over the -authenticator from @manpage{krb5_mk_req,3} and, in case of mutual -authentication, verifying the result from the server with -@manpage{krb5_rd_rep,3}. - -@example - status = krb5_sendauth (context, - &auth_context, - &sock, - VERSION, - NULL, - server, - AP_OPTS_MUTUAL_REQUIRED, - NULL, - NULL, - NULL, - NULL, - NULL, - NULL); - if (status) - krb5_err (context, 1, status, "krb5_sendauth"); -@end example - -Once authentication has been performed, it is time to send some -data. First we create a krb5_data structure, then we sign it with -@manpage{krb5_mk_safe,3} using the @code{auth_context} that contains the -session-key that was exchanged in the -@manpage{krb5_sendauth,3}/@manpage{krb5_recvauth,3} authentication -sequence. - -@example - data.data = "hej"; - data.length = 3; - - krb5_data_zero (&packet); - - status = krb5_mk_safe (context, - auth_context, - &data, - &packet, - NULL); - if (status) - krb5_err (context, 1, status, "krb5_mk_safe"); -@end example - -And send it over the network. - -@example - len = packet.length; - net_len = htonl(len); - - if (krb5_net_write (context, &sock, &net_len, 4) != 4) - err (1, "krb5_net_write"); - if (krb5_net_write (context, &sock, packet.data, len) != len) - err (1, "krb5_net_write"); -@end example - -To send encrypted (and signed) data @manpage{krb5_mk_priv,3} should be -used instead. @manpage{krb5_mk_priv,3} works the same way as -@manpage{krb5_mk_safe,3}, with the exception that it encrypts the data -in addition to signing it. - -@example - data.data = "hemligt"; - data.length = 7; - - krb5_data_free (&packet); - - status = krb5_mk_priv (context, - auth_context, - &data, - &packet, - NULL); - if (status) - krb5_err (context, 1, status, "krb5_mk_priv"); -@end example - -And send it over the network. - -@example - len = packet.length; - net_len = htonl(len); - - if (krb5_net_write (context, &sock, &net_len, 4) != 4) - err (1, "krb5_net_write"); - if (krb5_net_write (context, &sock, packet.data, len) != len) - err (1, "krb5_net_write"); - -@end example - -The server is using @manpage{krb5_rd_safe,3} and -@manpage{krb5_rd_priv,3} to verify the signature and decrypt the packet. - -@node Validating a password in a server application, API differences to MIT Kerberos, Walkthrough of a sample Kerberos 5 client, Programming with Kerberos -@section Validating a password in an application - -See the manual page for @manpage{krb5_verify_user,3}. - -@node API differences to MIT Kerberos, File formats, Validating a password in a server application, Programming with Kerberos -@section API differences to MIT Kerberos - -This section is somewhat disorganised, but so far there is no overall -structure to the differences, though some of the have their root in -that Heimdal uses an ASN.1 compiler and MIT doesn't. - -@subsection Principal and realms - -Heimdal stores the realm as a @code{krb5_realm}, that is a @code{char *}. -MIT Kerberos uses a @code{krb5_data} to store a realm. - -In Heimdal @code{krb5_principal} doesn't contain the component -@code{name_type}; it's instead stored in component -@code{name.name_type}. To get and set the nametype in Heimdal, use -@manpage{krb5_principal_get_type,3} and -@manpage{krb5_principal_set_type,3}. - -For more information about principal and realms, see -@manpage{krb5_principal,3}. - -@subsection Error messages - -To get the error string, Heimdal uses -@manpage{krb5_get_error_string,3} or, if @code{NULL} is returned, -@manpage{krb5_get_err_text,3}. This is to return custom error messages -(like ``Can't find host/datan.example.com@@EXAMPLE.COM in -/etc/krb5.conf.'' instead of a ``Key table entry not found'' that -@manpage{error_message,3} returns. - -Heimdal uses a threadsafe(r) version of the com_err interface; the -global @code{com_err} table isn't initialised. Then -@manpage{error_message,3} returns quite a boring error string (just -the error code itself). - - -@c @node Why you should use GSS-API for new applications, Walkthrough of a sample GSS-API client, Validating a password in a server application, Programming with Kerberos -@c @section Why you should use GSS-API for new applications -@c -@c SSPI, bah, bah, microsoft, bah, bah, almost GSS-API. -@c -@c It would also be possible for other mechanisms then Kerberos, but that -@c doesn't exist any other GSS-API implementations today. -@c -@c @node Walkthrough of a sample GSS-API client, , Why you should use GSS-API for new applications, Programming with Kerberos -@c @section Walkthrough of a sample GSS-API client -@c -@c Write about how gssapi_clent.c works. - -@node File formats, , API differences to MIT Kerberos, Programming with Kerberos -@section File formats - -This section documents the diffrent file formats that are used in -Heimdal and other Kerberos implementations. - -@subsection keytab - -The keytab binary format is not a standard format. The format has -evolved and may continue to. It is however understood by several -Kerberos implementations including Heimdal, MIT, Sun's Java ktab and -are created by the ktpass.exe utility from Windows. So it has -established itself as the defacto format for storing Kerberos keys. - -The following C-like structure definitions illustrate the MIT keytab -file format. All values are in network byte order. All text is ASCII. - -@example - keytab @{ - uint16_t file_format_version; /* 0x502 */ - keytab_entry entries[*]; - @}; - - keytab_entry @{ - int32_t size; - uint16_t num_components; /* subtract 1 if version 0x501 */ - counted_octet_string realm; - counted_octet_string components[num_components]; - uint32_t name_type; /* not present if version 0x501 */ - uint32_t timestamp; - uint8_t vno8; - keyblock key; - uint32_t vno; /* only present if >= 4 bytes left in entry */ - @}; - - counted_octet_string @{ - uint16_t length; - uint8_t data[length]; - @}; - - keyblock @{ - uint16_t type; - counted_octet_string; - @}; -@end example - -All numbers are stored in network byteorder (big endian) format. - -The keytab file format begins with the 16 bit file_format_version which -at the time this document was authored is 0x502. The format of older -keytabs is described at the end of this document. - -The file_format_version is immediately followed by an array of -keytab_entry structures which are prefixed with a 32 bit size indicating -the number of bytes that follow in the entry. Note that the size should be -evaluated as signed. This is because a negative value indicates that the -entry is in fact empty (e.g. it has been deleted) and that the negative -value of that negative value (which is of course a positive value) is -the offset to the next keytab_entry. Based on these size values alone -the entire keytab file can be traversed. - -The size is followed by a 16 bit num_components field indicating the -number of counted_octet_string components in the components array. - -The num_components field is followed by a counted_octet_string -representing the realm of the principal. - -A counted_octet_string is simply an array of bytes prefixed with a 16 -bit length. For the realm and name components, the counted_octet_string -bytes are ASCII encoded text with no zero terminator. - -Following the realm is the components array that represents the name of -the principal. The text of these components may be joined with slashs -to construct the typical SPN representation. For example, the service -principal HTTP/www.foo.net@@FOO.NET would consist of name components -"HTTP" followed by "www.foo.net". - -Following the components array is the 32 bit name_type (e.g. 1 is -KRB5_NT_PRINCIPAL, 2 is KRB5_NT_SRV_INST, 5 is KRB5_NT_UID, etc). In -practice the name_type is almost certainly 1 meaning KRB5_NT_PRINCIPAL. - -The 32 bit timestamp indicates the time the key was established for that -principal. The value represents the number of seconds since Jan 1, 1970. - -The 8 bit vno8 field is the version number of the key. This value is -overridden by the 32 bit vno field if it is present. The vno8 field is -filled with the lower 8 bits of the 32 bit protocol kvno field. - -The keyblock structure consists of a 16 bit value indicating the -encryption type and is a counted_octet_string containing the key. The -encryption type is the same as the Kerberos standard (e.g. 3 is -des-cbc-md5, 23 is arcfour-hmac-md5, etc). - -The last field of the keytab_entry structure is optional. If the size of -the keytab_entry indicates that there are at least 4 bytes remaining, -a 32 bit value representing the key version number is present. This -value supersedes the 8 bit vno8 value preceeding the keyblock. - -Older keytabs with a file_format_version of 0x501 are different in -three ways: - -@table @asis -@item All integers are in host byte order [1]. -@item The num_components field is 1 too large (i.e. after decoding, decrement by 1). -@item The 32 bit name_type field is not present. -@end table - -[1] The file_format_version field should really be treated as two -separate 8 bit quantities representing the major and minor version -number respectively. - -@subsection Heimdal database dump file - -Format of the Heimdal text dump file as of Heimdal 0.6.3: - -Each line in the dump file is one entry in the database. - -Each field of a line is separated by one or more spaces, with the -exception of fields consisting of principals containing spaces, where -space can be quoted with \ and \ is quoted by \. - -Fields and their types are: - -@example - Quoted princial (quote character is \) [string] - Keys [keys] - Created by [event] - Modified by [event optional] - Valid start time [time optional] - Valid end time [time optional] - Password end valid time [time optional] - Max lifetime of ticket [time optional] - Max renew time of ticket [integer optional] - Flags [hdb flags] - Generation number [generation optional] - Extensions [extentions optional] -@end example - -Fields following these silently are ignored. - -All optional fields will be skipped if they fail to parse (or comprise -the optional field marker of "-", w/o quotes). - -Example: - -@example -fred@@EXAMPLE.COM 27:1:16:e8b4c8fc7e60b9e641dcf4cff3f08a701d982a2f89ba373733d26ca59ba6c789666f6b8bfcf169412bb1e5dceb9b33cda29f3412:-:1:3:4498a933881178c744f4232172dcd774c64e81fa6d05ecdf643a7e390624a0ebf3c7407a:-:1:2:b01934b13eb795d76f3a80717d469639b4da0cfb644161340ef44fdeb375e54d684dbb85:-:1:1:ea8e16d8078bf60c781da90f508d4deccba70595258b9d31888d33987cd31af0c9cced2e:- 20020415130120:admin@@EXAMPLE.COM 20041221112428:fred@@EXAMPLE.COM - - - 86400 604800 126 20020415130120:793707:28 - -@end example - -Encoding of types are as follows: - -@table @asis -@item keys - -@example -kvno:[masterkvno:keytype:keydata:salt]@{zero or more separated by :@} -@end example - -kvno is the key version number. - -keydata is hex-encoded - -masterkvno is the kvno of the database master key. If this field is -empty, the kadmin load and merge operations will encrypt the key data -with the master key if there is one. Otherwise the key data will be -imported asis. - -salt is encoded as "-" (no/default salt) or - -@example -salt-type / -salt-type / "string" -salt-type / hex-encoded-data -@end example - -keytype is the protocol enctype number; see enum ENCTYPE in -include/krb5_asn1.h for values. - -Example: -@example -27:1:16:e8b4c8fc7e60b9e641dcf4cff3f08a701d982a2f89ba373733d26ca59ba6c789666f6b8bfcf169412bb1e5dceb9b33cda29f3412:-:1:3:4498a933881178c744f4232172dcd774c64e81fa6d05ecdf643a7e390624a0ebf3c7407a:-:1:2:b01934b13eb795d76f3a80717d469639b4da0cfb644161340ef44fdeb375e54d684dbb85:-:1:1:ea8e16d8078bf60c781da90f508d4deccba70595258b9d31888d33987cd31af0c9cced2e:- -@end example - - -@example -kvno=27,@{key: masterkvno=1,keytype=des3-cbc-sha1,keydata=..., default salt@}... -@end example - -@item time - -Format of the time is: YYYYmmddHHMMSS, corresponding to strftime -format "%Y%m%d%k%M%S". - -Time is expressed in UTC. - -Time can be optional (using -), when the time 0 is used. - -Example: - -@example -20041221112428 -@end example - -@item event - -@example - time:principal -@end example - -time is as given in format time - -principal is a string. Not quoting it may not work in earlier -versions of Heimdal. - -Example: -@example -20041221112428:bloggs@@EXAMPLE.COM -@end example - -@item hdb flags - -Integer encoding of HDB flags, see HDBFlags in lib/hdb/hdb.asn1. Each -bit in the integer is the same as the bit in the specification. - -@item generation: - -@example -time:usec:gen -@end example - - -usec is a the microsecond, integer. -gen is generation number, integer. - -The generation can be defaulted (using '-') or the empty string - -@item extensions: - -@example -first-hex-encoded-HDB-Extension[:second-...] -@end example - -HDB-extension is encoded the DER encoded HDB-Extension from -lib/hdb/hdb.asn1. Consumers HDB extensions should be aware that -unknown entires needs to be preserved even thought the ASN.1 data -content might be unknown. There is a critical flag in the data to show -to the KDC that the entry MUST be understod if the entry is to be -used. - -@end table |