sso.h 5.13 KB
Newer Older
1
2
3
4
5
6
7
8
9
#ifndef __sso_H
#define __sso_H 1

#ifdef __cplusplus
extern "C" {
#endif

#include <time.h>

ale's avatar
ale committed
10
#define SSO_TICKET_VERSION "4"
11

ale's avatar
ale committed
12
13
14
15
16
17
18
19
20
21
22
23
#define SSO_OK 0
#define SSO_ERR_SERIALIZATION -1
#define SSO_ERR_DESERIALIZATION -2
#define SSO_ERR_SIGNATURE -3
#define SSO_ERR_BUFFER_TOO_SMALL -4
#define SSO_ERR_BAD_SIGNATURE -5
#define SSO_ERR_UNSUPPORTED_VERSION -6
#define SSO_ERR_EXPIRED -7
#define SSO_ERR_BAD_SERVICE -8
#define SSO_ERR_BAD_DOMAIN -9
#define SSO_ERR_NO_MATCHING_GROUPS -10
#define SSO_ERR_DECODE64 -11
ale's avatar
ale committed
24
#define SSO_ERR_BAD_NONCE -12
ale's avatar
ale committed
25
26
#define SSO_ERR_MISSING_REQUIRED_FIELD -13
#define SSO_ERR_INVALID_FIELD -14
ale's avatar
ale committed
27
28
29

#define SSO_PUBLIC_KEY_SIZE 32
#define SSO_SECRET_KEY_SIZE 64
30
31
32
33
34

struct sso_ticket {
  char *user;
  char *service;
  char *domain;
ale's avatar
ale committed
35
  char *nonce;
36
37
  char **groups;
  time_t expires;
ale's avatar
ale committed
38
39
};

40
41
typedef struct sso_ticket *sso_ticket_t;

42
43
44
45
46
47
48
/** Create a new sso_ticket.
 *
 * Assembles a new sso_ticket struct with the given parameters.
 *
 * @param user Username.
 * @param service SSO service (including mandatory trailing slash).
 * @param domain SSO authentication domain.
ale's avatar
ale committed
49
 * @param nonce Unique nonce.
50
51
52
53
54
55
 * @param groups Group membership for this user (NULL-terminated array of
 *        strings).
 * @param validity_seconds Set the expiration time, based on current time.
 * @return A pointer to a newly allocated sso_ticket structure, which you must
 *         then free with sso_ticket_free().
 */
ale's avatar
ale committed
56
sso_ticket_t sso_ticket_new(const char *user, const char *service,
ale's avatar
ale committed
57
58
                            const char *domain, const char *nonce,
                            const char **groups, int validity_seconds);
59

60
61
62
63
/** Free the memory used by a sso_ticket.
 *
 * @param t Pointer to the sso_ticket to free.
 */
64
void sso_ticket_free(sso_ticket_t t);
ale's avatar
ale committed
65

66
67
68
69
70
71
72
73
74
75
76
/** Sign a sso_ticket using a secret key.
 *
 * Signs and encodes a ticket to a serialized ASCII form.
 *
 * @param[in] t Pointer to the sso_ticket to sign.
 * @param[in] secret_key Secret key. This must be a buffer of
 *            exactly SSO_SECRET_KEY_SIZE bytes.
 * @param[out] out Output buffer.
 * @param[in] outsz Size of the available output buffer.
 * @return An error code in case of failure, SSO_OK otherwise.
 */
ale's avatar
ale committed
77
78
int sso_ticket_sign(sso_ticket_t t, const unsigned char *secret_key, char *out,
                    size_t outsz);
ale's avatar
ale committed
79

80
81
82
83
/** Generate a pair of public and private keys.
 *
 * Note that the resulting buffers will contain binary data, not
 * NULL-terminated strings. Key sizes are constant, use the
ale's avatar
ale committed
84
 * SSO_PUBLIC_KEY_SIZE and SSO_SECRET_KEY_SIZE macros.
ale's avatar
ale committed
85
 *
ale's avatar
ale committed
86
 * @param[out] publicp Pointer to a buffer of at least SSO_PUBLIC_KEY_SIZE
87
88
89
90
91
 *             bytes.
 * @param[out] secretp Pointer to a buffer of at least SSO_SECRET_KEY_SIZE
 *             bytes.
 * @returns An error code in case of failure, SSO_OK otherwise.
 */
92
int sso_generate_keys(unsigned char *publicp, unsigned char *secretp);
ale's avatar
ale committed
93

94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
/** Decode a serialized sso_ticket and validate its signature.
 *
 * This function decodes a ticket from its serialized ASCII form (as
 * generated by sso_ticket_sign), and verifies its cryptographic
 * signature against the provided public key.
 *
 * You must call sso_validate() after this function, to validate
 * the sso_ticket contents.
 *
 * @param[out] t Pointer to a sso_ticket_t that will hold the decoded
 *             sso_ticket. The resulting pointer should be freed by
 *             calling sso_ticket_free().
 * @param[in] str ASCII-encoded serialized ticket.
 * @param[in] public_key Public key. This must be a
 *            buffer of exactly SSO_PUBLIC_KEY_SIZE bytes.
 * @returns An error code in case of failure, SSO_OK otherwise.
 */
ale's avatar
ale committed
111
112
int sso_ticket_open(sso_ticket_t *t, const char *str,
                    const unsigned char *public_key);
ale's avatar
ale committed
113

114
115
116
117
118
119
120
121
122
123
124
125
126
/** Validate sso_ticket contents.
 *
 * Tickets returned by sso_ticket_open() must be validated in the
 * application context:
 *
 * - 'service' and 'domain' must match
 * - expiration date should not be past current time
 * - if 'groups' is non-NULL, the intersection between 'groups' and
 *   the groups specified in the ticket must not be empty.
 *
 * @param t Pointer to the sso_ticket to validate.
 * @param service SSO service (including trailing slash).
 * @param domain SSO authentication domain.
ale's avatar
ale committed
127
 * @param nonce Unique nonce that should match the one in the ticket.
128
129
130
131
132
 * @param groups List of groups that the user should be a member of
 *        (NULL-terminated list of strings). Note that any matching
 *        group will do.
 * @returns An error code in case of failure, SSO_OK otherwise.
 */
ale's avatar
ale committed
133
int sso_validate(sso_ticket_t t, const char *service, const char *domain,
ale's avatar
ale committed
134
                 const char *nonce, const char **groups);
135

136
137
138
139
140
141
/** Return a user-readable string corresponding to a SSO error code.
 *
 * @param err Error code.
 * @returns A pointer to a statically-allocated string. Does not need
 *          to be freed.
 */
142
143
144
145
146
147
148
149
150
151
152
const char *sso_strerror(int err);

/* Base64 encoding utilities. */
int sso_base64_encode(unsigned char *dst, size_t *dlen,
                      const unsigned char *src, size_t slen);
int sso_base64_decode(unsigned char *dst, size_t *dlen,
                      const unsigned char *src, size_t slen);
size_t sso_base64_encode_size(size_t slen);

#ifdef __cplusplus
}
ale's avatar
ale committed
153
#endif
154
155

#endif /* __sso_H */