domainkey.h
来自「MiniSip Client with DomainKeys Authentic」· C头文件 代码 · 共 307 行
H
307 行
#ifndef DOMAINKEY_H_#define DOMAINKEY_H_#include <libmcrypto/config.h>#include <openssl/pem.h>#include <openssl/evp.h>#include <libmutil/Exception.h>#include <time.h>#include <sys/types.h>#include <sys/stat.h>#include <unistd.h>#include <netinet/in.h>#include <arpa/nameser.h>#include <resolv.h>#include <libmcrypto/OpenSSLUtil.h>#include <iostream>#include <fstream>#include <string>#include <list>#include <stddef.h>#include <stdio.h>#include <stdlib.h>#include <sys/types.h>#include <dirent.h>/** * This class represents a DomainKey (RSA Public Key). * According to the standard (RFC XXXX) the public keys are stored as a txt-record on a dns server. Once the key is fetched, it will be cached locally. * The implementation of this class referes to the openssl library. For querying the dns server, libresolv is used, too. */class LIBMCRYPTO_API DomainKey{ public: /** * The constructor creates a new domain key. * In this case, the local cache is checked for the corresponding key. If the key does not exist, the dns server is queried for the key. * @param sipuri A String representing the SIP-URI of the desired domain key. i.e. foo@bar.com */ DomainKey(std::string sipuri); /** * Destructor for the domain key. */ ~DomainKey(); /** * This method verifies the signature of a data block. * The verification process is implemented with the openssl functions. * @param data byte_t array with the data * @param dataLength The length of the data * @param signature byte_t array with the signature * @param signatureLength The length of the signatur * @return boolean value which indicates if the verification is ok or not */ bool verify(byte_t* data, unsigned int dataLength, byte_t* signature, unsigned int signatureLength); /** * Static method to delete a specific cache entry in the cache folder * @param sipuri A String representing the SIP-URI of the domainkey to be deleted. */ static void deleteCacheEntry(std::string sipuri); /** * This static method deletes all cached domainkeys in the cache directory. */ static void deleteCacheEntries(); /** * All cache entries will be listed by their SIP-URI * @return List of strings representing the SIP-URIs of the cached domainkeys. */ static std::list<std::string> listCacheEntries(); /** * Path to the cache directory */ static const std::string CACHE_DIR; private: /** * openssl public key. */ EVP_PKEY* publicKey; /** * This method checks if the desired domainkey is already chached. * The filename is derived from the SIP-URI: foo@bar.com --> foo._domainkey.bar.com --> foo._domainkey.bar.com.pem * @param filename Filename (whole path) * @return boolean value if the cache entry exists */ bool checkPublicKeyFile(std::string filename); /** * Loads the cached domainkey (public key) from a local file. * The filename is derived from the SIP-URI: foo@bar.com --> foo._domainkey.bar.com --> foo._domainkey.bar.com.pem * @param filename Filename (whole path) * @return boolean value if loading was successful */ bool loadPublicKeyFromFile(std::string filename); /** * Saves the public key into the local cache. * The filename is derived from the SIP-URI: foo@bar.com --> foo._domainkey.bar.com --> foo._domainkey.bar.com.pem * @param filename Filename (whole path) */ void savePublicKeyFile(std::string filename); /** * This method queries the corresponding dns-server to get the public key. * For querying the dns-server res_query() from libresolv is used. * The answer of the dns-server has the following format according to RFC 1035: * * +---------------------+ * | Header | * +---------------------+ * | Question | the question for the name server * +---------------------+ * | Answer | RRs answering the question * +---------------------+ * | Authority | RRs pointing toward an authority * +---------------------+ * | Additional | RRs holding additional information * +---------------------+ * * The header contains the following fields: * * 1 1 1 1 1 1 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | ID | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * |QR| Opcode |AA|TC|RD|RA| Z | RCODE | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | QDCOUNT | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | ANCOUNT | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | NSCOUNT | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | ARCOUNT | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * * * Question section format: * * 1 1 1 1 1 1 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | | * / QNAME / * / / * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | QTYPE | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | QCLASS | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * * where: * * QNAME a domain name represented as a sequence of labels, where * each label consists of a length octet followed by that * number of octets. The domain name terminates with the * zero length octet for the null label of the root. Note * that this field may be an odd number of octets; no * padding is used. * * QTYPE a two octet code which specifies the type of the query. * The values for this field include all codes valid for a * TYPE field, together with some more general codes which * can match more than one type of RR. * * QCLASS a two octet code that specifies the class of the query. * For example, the QCLASS field is IN for the Internet. * * * Resource record format: * * 1 1 1 1 1 1 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | | * / / * / NAME / * | | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | TYPE | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | CLASS | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | TTL | * | | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | RDLENGTH | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--| * / RDATA / * / / * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * * where: * * NAME a domain name to which this resource record pertains. * * TYPE two octets containing one of the RR type codes. This * field specifies the meaning of the data in the RDATA * field. * * CLASS two octets which specify the class of the data in the * RDATA field. * * TTL a 32 bit unsigned integer that specifies the time * interval (in seconds) that the resource record may be * cached before it should be discarded. Zero values are * interpreted to mean that the RR can only be used for the * transaction in progress, and should not be cached. * * RDLENGTH an unsigned 16 bit integer that specifies the length in * octets of the RDATA field. * * RDATA a variable length string of octets that describes the * resource. The format of this information varies * according to the TYPE and CLASS of the resource record. * For example, the if the TYPE is A and the CLASS is IN, * the RDATA field is a 4 octet ARPA Internet address. * * * @param sipuri A String representing the SIP-URI */ void fetchPublicKey(std::string sipuri); /** * Converts the SIP-URI to the DNS-URL. * The DNS-URL is derived from the SIP-URI: foo@bar.com --> foo._domainkey.bar.com * @param sipuri A String representing the SIP-URI * @return String representing the DNS-URL */ static std::string getDNSURL(std::string sipuri); /** * Converts the DNS-URL back to the SIP-URI * The SIP-URI is derived from the DNS-URL: foo._domainkey.bar.com --> foo@bar.com * @param dnsurl A String representing the DNS-URL * @return String representing the SIP-URI */ static std::string getSipURI(std::string dnsurl); /** * This method extracts the qname of the question section of the dns answer. * * 1 1 1 1 1 1 * 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | | * / QNAME / * / / * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | QTYPE | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * | QCLASS | * +--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+--+ * * where: * * QNAME a domain name represented as a sequence of labels, where * each label consists of a length octet followed by that * number of octets. The domain name terminates with the * zero length octet for the null label of the root. Note * that this field may be an odd number of octets; no * padding is used. * * @param answer char array representing the dns answer * @param index index of the beginning of qname * @param qname_string Is a string in which the qname is stored * @return The length of the qname (bytes used in the answer) */ int extractLabel(unsigned char * answer, int index, std::string& qname_string); /** * Extracts the public key from the answer txt record. * The public key is being extracted from the txt record. This extracted string is going the be formated as follows: * - "-----BEGIN PUBLIC KEY-----\n" is inserted before the key * - "\n-----END PUBLIC KEY-----" is inserted after the key * - after every 64 byte a new line is inserted * * @param answer_txt String representing the txt record. * @return public key in openssl format */ EVP_PKEY* extractPublicKey(std::string answer_txt); /** * This method checks if the cache directory exists for storing the files. * If the directory does not exist, it will be created */ void checkCacheDirectory();};class LIBMCRYPTO_API DomainKeyException : public Exception{ public: /** * DomainKey exception representing an exception withing the domain key. * @param desc Description of the exception */ DomainKeyException( const char *desc):Exception(desc){};};#endif /*DOMAINKEY_H_*/
⌨️ 快捷键说明
复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?