1 /*_############################################################################
6 _## -----------------------------------------------
7 _## Copyright (c) 2001-2010 Jochen Katz, Frank Fock
9 _## This software is based on SNMP++2.6 from Hewlett Packard:
11 _## Copyright (c) 1996
12 _## Hewlett-Packard Company
14 _## ATTENTION: USE OF THIS SOFTWARE IS SUBJECT TO THE FOLLOWING TERMS.
15 _## Permission to use, copy, modify, distribute and/or sell this software
16 _## and/or its documentation is hereby granted without fee. User agrees
17 _## to display the above copyright notice and this license notice in all
18 _## copies of the software and any documentation of the software. User
19 _## agrees to assume all liability for the use of the software;
20 _## Hewlett-Packard and Jochen Katz make no representations about the
21 _## suitability of this software for any purpose. It is provided
22 _## "AS-IS" without warranty of any kind, either express or implied. User
23 _## hereby grants a royalty-free license to any and all derivatives based
24 _## upon this software code base.
26 _## Stuttgart, Germany, Thu Sep 2 00:07:47 CEST 2010
28 _##########################################################################*/
29 // $Id: auth_priv.h 345 2008-10-29 20:14:40Z katz $
34 #include "snmp_pp/config_snmp_pp.h"
38 #include "snmp_pp/usm_v3.h"
40 #ifdef SNMP_PP_NAMESPACE
44 #define SNMPv3_USM_MAX_KEY_LEN 32
46 /* Accept Messages with auth/priv param fields up to this length */
47 #define SNMPv3_AP_MAXLENGTH_AUTHPARAM 128
48 #define SNMPv3_AP_MAXLENGTH_PRIVPARAM 128
51 #define SNMPv3_AP_OUTPUT_LENGTH_MD5 16
52 #define SNMPv3_AP_OUTPUT_LENGTH_SHA 20
57 * Abstract class for auth modules.
59 * This class has to be subclassed to add new authentication
70 * Generate the localized key for the given password and engine id.
72 * @param password - the password
73 * @param password_len - the length of the password
74 * @param engine_id - pointer to snmpEngineID
75 * @param engine_id_len - length of snmpEngineID
76 * @param key - pointer to an empty buffer that will be filled
78 * @param key_len - IN: length of the buffer
79 * OUT: length of the key
81 * @return SNMPv3_USM_OK on success
83 virtual int password_to_key(const unsigned char *password,
84 const unsigned int password_len,
85 const unsigned char *engine_id,
86 const unsigned int engine_id_len,
88 unsigned int *key_len) = 0;
91 * Generate a hash value for the given data.
93 * @param data - the data
94 * @param data_len - the length of the data
95 * @param digest - pointer to the generated digest
97 * @return SNMPv3_USM_OK on success
99 virtual int hash(const unsigned char *data,
100 const unsigned int data_len,
101 unsigned char *digest) const = 0;
104 * Authenticate an outgoing message.
106 * This method fills the authentication parameters field of the
107 * given message. The param auth_par_ptr is pointing inside the
108 * message buffer and must be zeroed before the authentication value
111 * @param key - pointer to the (fixed length) key
112 * @param msg - pointer to the whole message
113 * @param msg_len - the length of the message
114 * @param auth_par_ptr - pointer to the auth field inside the msg buffer
116 * @return SNMPv3_USM_OK on success and
117 * SNMPv3_USM_ERROR for unexpected errors.
119 virtual int auth_out_msg(const unsigned char *key,
122 unsigned char *auth_par_ptr) = 0;
126 * Authenticate an incoming message.
128 * This method checks if the value in the authentication parameters
129 * field of the message is valid.
131 * The following procedure is used to verify the authenitcation value
132 * - copy the authentication value to a temp buffer
133 * - zero the auth field
134 * - recalculate the authenthication value
135 * - compare the two authentcation values
136 * - write back the received authentication value if values differ
138 * @param key - pointer to the (fixed length) key
139 * @param msg - pointer to the whole message
140 * @param msg_len - the length of the message
141 * @param auth_par_ptr - pointer to the auth field inside the msg buffer
142 * @param auth_par_len - Length of the received auth field
144 * @return SNMPv3_USM_OK if the msg is valid,
145 * SNMPv3_USM_AUTHENTICATION_FAILURE if not and
146 * SNMPv3_USM_ERROR for unexpected errors.
148 virtual int auth_inc_msg(const unsigned char *key,
151 unsigned char *auth_par_ptr,
152 const int auth_par_len) = 0;
155 * Get the unique id of the authentication protocol.
157 virtual int get_id() const = 0;
161 * Get the unique identifier string of the authentication protocol.
163 virtual const char *get_id_string() const = 0;
166 * Set the pointer to the salt that should be used.
168 virtual void set_salt(pp_uint64 *new_salt) { salt = new_salt; };
171 * Get the maximum length that is needed for the
172 * msgAuthenticationParameters field.
174 virtual int get_auth_params_len() const = 0;
177 * Get length of a hash output.
179 virtual int get_hash_len() const = 0;
187 * Abstract class for priv modules
189 * This class has to be subclassed to add new privacy
199 * Encrypt the buffer with the given key.
201 * This method fills the privacy parameters field of the given
204 * @param key - pointer to the encryption key
205 * @param key_len - length of encryption key
206 * @param buffer - pointer to the unencrypted buffer
207 * @param buffer_len - length of the buffer
208 * @param out_buffer - pointer to the buffer for the encryptet data
209 * @param out_buffer_len - Input: Length of the output buffer.
210 * Output: Bytes written
211 * @param privacy_params - Buffer, where the privacy parameters
213 * @param privacy_params_len - Length of the privacy parameters buffer
214 * @param engine_boots - The engine boots value for the message
215 * @param engine_time - The engine time value for the message
217 * @return SNMPv3_USM_OK on success
219 virtual int encrypt(const unsigned char *key,
220 const unsigned int key_len,
221 const unsigned char *buffer,
222 const unsigned int buffer_len,
223 unsigned char *out_buffer,
224 unsigned int *out_buffer_len,
225 unsigned char *privacy_params,
226 unsigned int *privacy_params_len,
227 const unsigned long engine_boots,
228 const unsigned long engine_time) = 0;
232 * Decrypt the buffer with the given key.
234 * This method needs the privacy parameters field for the given
237 * @param key - pointer to the (fixed length) dencryption key
238 * @param key_len - length of encryption key
239 * @param buffer - pointer to the encrypted buffer
240 * @param buffer_len - length of the buffer
241 * @param out_buffer - pointer to the buffer for the decryptet data
242 * @param out_buffer_len - Input: Length of the output buffer.
243 * Output: Bytes written
244 * @param privacy_params - Buffer, where the privacy parameters
246 * @param privacy_params_len - Length of the privacy parameters buffer
247 * @param engine_boots - The engine boots value for the message
248 * @param engine_time - The engine time value for the message
250 * @return SNMPv3_USM_OK on success
252 virtual int decrypt(const unsigned char *key,
253 const unsigned int key_len,
254 const unsigned char *buffer,
255 const unsigned int buffer_len,
256 unsigned char *out_buffer,
257 unsigned int *out_buffer_len,
258 const unsigned char *privacy_params,
259 const unsigned int privacy_params_len,
260 const unsigned long engine_boots,
261 const unsigned long engine_time) = 0;
264 * Extend a localized key that is too short.
266 * Some privacy protocols require a key that is longer than the key
267 * generated by the pasword to key algorithm of the authentication
268 * protocol. This function extends a short key to the required length.
270 * @param password - the password
271 * @param password_len - the length of the password
272 * @param engine_id - pointer to snmpEngineID
273 * @param engine_id_len - length of snmpEngineID
274 * @param key - pointer to the short key that was generated
275 * using Auth::password_to_key() function
276 * @param key_len - IN: length of the short key
277 * OUT: length of the extended key
278 * @param max_key_len - Length of the key buffer
279 * @param auth - Pointer of the authentication protocol that
282 * @return SNMPv3_USM_OK on success
285 virtual int extend_short_key(const unsigned char *password,
286 const unsigned int password_len,
287 const unsigned char *engine_id,
288 const unsigned int engine_id_len,
290 unsigned int *key_len,
291 const unsigned int max_key_len,
295 * Get the uniqhe id of the privacy protocol.
297 virtual int get_id() const = 0;
300 * Get the unique identifier string of the privacy protocol.
302 virtual const char *get_id_string() const = 0;
305 * Set the pointer to the salt that should be used.
307 virtual void set_salt(pp_uint64 *new_salt) { salt = new_salt; };
310 * Get the maximum length that is needed for the
311 * msgPrivacyParameters field.
313 virtual int get_priv_params_len() const = 0;
316 * Get the minimum key length needed for encryption and decryption.
318 virtual int get_min_key_len() const = 0;
321 * Decrease a too long length to the right value.
323 virtual void fix_key_len(unsigned int &key_len) const = 0;
330 typedef Auth* AuthPtr;
331 typedef Priv* PrivPtr;
335 * Class that holds all authentication and privacy protocols
338 class DLLOPT AuthPriv
343 * Default constructor, initializes random values
345 AuthPriv(int &construct_state);
348 * Destructor, deletes all auth and priv protocol objets.
353 * Add the default authentication protocols.
355 * The following authentication protocols are added:
359 * The following privacy protocols are added:
361 * - AES128, AES192 and AES256 if libtomcrypt or OpenSSL is enabled
364 * @return SNMP_CLASS_SUCCESS or SNMP_CLASS_ERROR.
366 int add_default_modules();
369 * Add a new authentication protocol.
371 * All added objects will be deleted in the destructor
373 * @param auth - Pointer to a new auth protocol object
375 * @return SNMP_CLASS_SUCCESS or SNMP_CLASS_ERROR
377 int add_auth(Auth *auth);
380 * Delete a authentication protocol.
382 * @param auth_id - The id of the authentication protocol to remove
384 * @return SNMP_CLASS_SUCCESS or SNMP_CLASS_ERROR
386 int del_auth(const int auth_id);
389 * Add a new privacy protocol.
391 * All added objects will be deleted in the destructor
393 * @param priv - Pointer to a new privacy protocol object
395 * @return SNMP_CLASS_SUCCESS or SNMP_CLASS_ERROR
397 int add_priv(Priv *priv);
400 * Delete a privacy protocol.
402 * @param priv_id - The id of the privacy protocol to remove
404 * @return SNMP_CLASS_SUCCESS or SNMP_CLASS_ERROR
406 int del_priv(const int priv_id);
409 * Call the password-to-key method of the specified authentication
412 int password_to_key_auth(const int auth_prot,
413 const unsigned char *password,
414 const unsigned int password_len,
415 const unsigned char *engine_id,
416 const unsigned int engine_id_len,
418 unsigned int *key_len);
421 * Call the password-to-key method of the specified privacy
424 int password_to_key_priv(const int auth_prot,
426 const unsigned char *password,
427 const unsigned int password_len,
428 const unsigned char *engine_id,
429 const unsigned int engine_id_len,
431 unsigned int *key_len);
434 * Get the keyChange value for the specified keys using the given
435 * authentication protocol.
437 int get_keychange_value(const int auth_prot,
438 const OctetStr& old_key,
439 const OctetStr& new_key,
440 OctetStr& keychange_value);
443 * Get a pointer to a privacy protocol object.
445 Priv *get_priv(const int priv_prot);
448 * Get a pointer to a authentication protocol object.
450 Auth *get_auth(const int auth_prot);
453 * Get the unique id for the given auth protocol.
455 * @param string_id - The string returned by Auth::get_id_string()
457 * @return The id or -1
459 int get_auth_id(const char *string_id) const;
462 * Get the unique id for the given priv protocol.
464 * @param string_id - The string returned by Priv::get_id_string()
466 * @return The id or -1
468 int get_priv_id(const char *string_id) const;
473 int encrypt_msg(const int priv_prot,
474 const unsigned char *key,
475 const unsigned int key_len,
476 const unsigned char *buffer,
477 const unsigned int buffer_len,
478 unsigned char *out_buffer,
479 unsigned int *out_buffer_len,
480 unsigned char *privacy_params,
481 unsigned int *privacy_params_len,
482 const unsigned long engine_boots,
483 const unsigned long engine_time);
488 int decrypt_msg(const int priv_prot,
489 const unsigned char *key,
490 const unsigned int key_len,
491 const unsigned char *buffer,
492 const unsigned int buffer_len,
493 unsigned char *out_buffer,
494 unsigned int *out_buffer_len,
495 const unsigned char *privacy_params,
496 const unsigned int privacy_params_len,
497 const unsigned long engine_boots,
498 const unsigned long engine_time);
501 * Get the length of the authentication parameters field of the given
502 * authentication protocol.
504 int get_auth_params_len(const int auth_prot);
507 * Get the length of the privacy parameters field of the given
510 int get_priv_params_len(const int priv_prot);
513 * Fill in the authentication field of an outgoing message
515 int auth_out_msg(const int auth_prot,
516 const unsigned char *key,
519 unsigned char *auth_par_ptr);
522 * Check the authentication field of an incoming message
524 int auth_inc_msg(const int auth_prot,
525 const unsigned char *key,
528 unsigned char *auth_par_ptr,
529 const int auth_par_len);
533 AuthPtr *auth; ///< Array of pointers to Auth-objects
534 PrivPtr *priv; ///< Array of pointers to Priv-objects
535 int auth_size; ///< current size of the auth array
536 int priv_size; ///< current size of the priv array
537 pp_uint64 salt; ///< current salt value (64 bits)
542 * Authentication module using SHA.
546 class DLLOPT AuthSHA: public Auth
549 int password_to_key(const unsigned char *password,
550 const unsigned int password_len,
551 const unsigned char *engine_id,
552 const unsigned int engine_id_len,
554 unsigned int *key_len);
556 int hash(const unsigned char *data,
557 const unsigned int data_len,
558 unsigned char *digest) const;
560 int auth_out_msg(const unsigned char *key,
563 unsigned char *auth_par_ptr);
565 int auth_inc_msg(const unsigned char *key,
568 unsigned char *auth_par_ptr,
569 const int auth_par_len);
571 int get_id() const { return SNMP_AUTHPROTOCOL_HMACSHA; };
573 const char *get_id_string() const { return "HMAC-SHA"; };
575 int get_auth_params_len() const { return 12; };
577 int get_hash_len() const { return SNMPv3_AP_OUTPUT_LENGTH_SHA;};
581 * Authentication module using MD5.
585 class DLLOPT AuthMD5: public Auth
588 int password_to_key(const unsigned char *password,
589 const unsigned int password_len,
590 const unsigned char *engine_id,
591 const unsigned int engine_id_len,
593 unsigned int *key_len);
595 int hash(const unsigned char *data,
596 const unsigned int data_len,
597 unsigned char *digest) const;
599 int auth_out_msg(const unsigned char *key,
602 unsigned char *auth_par_ptr);
605 int auth_inc_msg(const unsigned char *key,
608 unsigned char *auth_par_ptr,
609 const int auth_par_len);
611 int get_id() const { return SNMP_AUTHPROTOCOL_HMACMD5; };
613 const char *get_id_string() const { return "HMAC-MD5"; };
615 int get_auth_params_len() const { return 12; };
617 int get_hash_len() const { return SNMPv3_AP_OUTPUT_LENGTH_MD5;};
621 * Encryption module using DES.
625 class DLLOPT PrivDES: public Priv
628 #if defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)
634 int encrypt(const unsigned char *key,
635 const unsigned int key_len,
636 const unsigned char *buffer,
637 const unsigned int buffer_len,
638 unsigned char *out_buffer,
639 unsigned int *out_buffer_len,
640 unsigned char *privacy_params,
641 unsigned int *privacy_params_len,
642 const unsigned long engine_boots,
643 const unsigned long engine_time);
645 int decrypt(const unsigned char *key,
646 const unsigned int key_len,
647 const unsigned char *buffer,
648 const unsigned int buffer_len,
649 unsigned char *out_buffer,
650 unsigned int *out_buffer_len,
651 const unsigned char *privacy_params,
652 const unsigned int privacy_params_len,
653 const unsigned long engine_boots,
654 const unsigned long engine_time);
656 int extend_short_key(const unsigned char *password,
657 const unsigned int password_len,
658 const unsigned char *engine_id,
659 const unsigned int engine_id_len,
661 unsigned int *key_len,
662 const unsigned int max_key_len,
664 { return SNMPv3_USM_ERROR; /* not needed for DES! */ };
666 int get_id() const { return SNMP_PRIVPROTOCOL_DES; };
667 const char *get_id_string() const { return "DES"; };
668 int get_priv_params_len() const { return 8; };
669 int get_min_key_len() const { return 16; };
670 void fix_key_len(unsigned int &key_len) const
671 { key_len = (key_len >= 16 ? 16 : 0); };
676 * Encryption module using IDEA.
680 class DLLOPT PrivIDEA: public Priv
684 int encrypt(const unsigned char *key,
685 const unsigned int key_len,
686 const unsigned char *buffer,
687 const unsigned int buffer_len,
688 unsigned char *out_buffer,
689 unsigned int *out_buffer_len,
690 unsigned char *privacy_params,
691 unsigned int *privacy_params_len,
692 const unsigned long engine_boots,
693 const unsigned long engine_time);
695 int decrypt(const unsigned char *key,
696 const unsigned int key_len,
697 const unsigned char *buffer,
698 const unsigned int buffer_len,
699 unsigned char *out_buffer,
700 unsigned int *out_buffer_len,
701 const unsigned char *privacy_params,
702 const unsigned int privacy_params_len,
703 const unsigned long engine_boots,
704 const unsigned long engine_time);
706 int extend_short_key(const unsigned char *password,
707 const unsigned int password_len,
708 const unsigned char *engine_id,
709 const unsigned int engine_id_len,
711 unsigned int *key_len,
712 const unsigned int max_key_len,
714 { return SNMPv3_USM_ERROR; /* not needed for IDEA! */ };
716 int get_id() const { return SNMP_PRIVPROTOCOL_IDEA; };
717 const char *get_id_string() const { return "IDEA"; };
718 int get_priv_params_len() const { return 8; };
719 int get_min_key_len() const { return 16; };
720 void fix_key_len(unsigned int &key_len) const
721 { key_len = (key_len >= 16 ? 16 : 0); };
727 #if defined(_USE_LIBTOMCRYPT) || defined(_USE_OPENSSL)
730 * Encryption module using AES (only available with libtomcrypt).
734 class DLLOPT PrivAES: public Priv
738 PrivAES(const int aes_type_);
740 int encrypt(const unsigned char *key,
741 const unsigned int key_len,
742 const unsigned char *buffer,
743 const unsigned int buffer_len,
744 unsigned char *out_buffer,
745 unsigned int *out_buffer_len,
746 unsigned char *privacy_params,
747 unsigned int *privacy_params_len,
748 const unsigned long engine_boots,
749 const unsigned long engine_time);
751 int decrypt(const unsigned char *key,
752 const unsigned int key_len,
753 const unsigned char *buffer,
754 const unsigned int buffer_len,
755 unsigned char *out_buffer,
756 unsigned int *out_buffer_len,
757 const unsigned char *privacy_params,
758 const unsigned int privacy_params_len,
759 const unsigned long engine_boots,
760 const unsigned long engine_time);
762 int extend_short_key(const unsigned char *password,
763 const unsigned int password_len,
764 const unsigned char *engine_id,
765 const unsigned int engine_id_len,
767 unsigned int *key_len,
768 const unsigned int max_key_len,
771 int get_id() const { return aes_type; };
772 const char *get_id_string() const;
773 int get_priv_params_len() const { return 8; };
774 int get_min_key_len() const { return key_bytes; };
775 void fix_key_len(unsigned int &key_len) const
776 { key_len = (key_len >= (unsigned)key_bytes ? key_bytes : 0); };
782 #if defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)
787 #endif // _USE_LIBTOMCRYPT or _USE_OPENSSL
791 * Encryption module using TripleDES-EDE KEY
796 #define TRIPLEDES_EDE_KEY_LEN 32
799 class DLLOPT Priv3DES_EDE: public Priv
802 #if defined(_USE_LIBTOMCRYPT) && !defined(_USE_OPENSSL)
809 int encrypt(const unsigned char *key,
810 const unsigned int key_len,
811 const unsigned char *buffer,
812 const unsigned int buffer_len,
813 unsigned char *out_buffer,
814 unsigned int *out_buffer_len,
815 unsigned char *privacy_params,
816 unsigned int *privacy_params_len,
817 const unsigned long engine_boots,
818 const unsigned long engine_time);
820 int decrypt(const unsigned char *key,
821 const unsigned int key_len,
822 const unsigned char *buffer,
823 const unsigned int buffer_len,
824 unsigned char *out_buffer,
825 unsigned int *out_buffer_len,
826 const unsigned char *privacy_params,
827 const unsigned int privacy_params_len,
828 const unsigned long engine_boots,
829 const unsigned long engine_time);
831 int extend_short_key(const unsigned char *password,
832 const unsigned int password_len,
833 const unsigned char *engine_id,
834 const unsigned int engine_id_len,
836 unsigned int *key_len,
837 const unsigned int max_key_len,
840 int get_id() const { return SNMP_PRIVPROTOCOL_3DESEDE; };
841 const char *get_id_string() const { return "3DESEDE"; };
842 int get_priv_params_len() const { return 8; };
843 int get_min_key_len() const { return TRIPLEDES_EDE_KEY_LEN; };
844 void fix_key_len(unsigned int &key_len) const
845 { key_len = (key_len >= TRIPLEDES_EDE_KEY_LEN
846 ? TRIPLEDES_EDE_KEY_LEN : 0); };
852 #endif // _USE_3DES_EDE
854 #ifdef SNMP_PP_NAMESPACE
855 } // end of namespace Snmp_pp