1e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/*************************************************************************** 2e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * _ _ ____ _ 3e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Project ___| | | | _ \| | 4e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * / __| | | | |_) | | 5e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * | (__| |_| | _ <| |___ 6e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * \___|\___/|_| \_\_____| 7e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 8e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Copyright (C) 1998 - 2015, Daniel Stenberg, <daniel@haxx.se>, et al. 9e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 10e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is licensed as described in the file COPYING, which 11e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * you should have received as part of this distribution. The terms 12d15eaac64ca1a7244824d660ea84e8815a23d058Alex Deymo * are also available at https://curl.haxx.se/docs/copyright.html. 13e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 14e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * You may opt to use, copy, modify, merge, publish, distribute and/or sell 15e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * copies of the Software, and permit persons to whom the Software is 16e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * furnished to do so, under the terms of the COPYING file. 17e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 18e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This software is distributed on an "AS IS" basis, WITHOUT WARRANTY OF ANY 19e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * KIND, either express or implied. 20e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 21e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ***************************************************************************/ 22e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_setup.h" 23e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 24e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef USE_METALINK 25e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 26e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include <sys/stat.h> 27e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 28e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef HAVE_FCNTL_H 29e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <fcntl.h> 30e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif 31e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 32e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef USE_OPENSSL 33e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <openssl/md5.h> 34e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <openssl/sha.h> 35e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#elif defined(USE_GNUTLS_NETTLE) 36e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <nettle/md5.h> 37e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <nettle/sha.h> 38e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define MD5_CTX struct md5_ctx 39e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define SHA_CTX struct sha1_ctx 40e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define SHA256_CTX struct sha256_ctx 41e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#elif defined(USE_GNUTLS) 42e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <gcrypt.h> 43e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define MD5_CTX gcry_md_hd_t 44e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define SHA_CTX gcry_md_hd_t 45e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define SHA256_CTX gcry_md_hd_t 46e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#elif defined(USE_NSS) 47e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <nss.h> 48e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <pk11pub.h> 49e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define MD5_CTX void * 50e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define SHA_CTX void * 51e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define SHA256_CTX void * 52e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET static NSSInitContext *nss_context; 53e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#elif defined(USE_POLARSSL) 54e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <polarssl/md5.h> 55e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <polarssl/sha1.h> 56e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <polarssl/sha256.h> 57e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define MD5_CTX md5_context 58e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define SHA_CTX sha1_context 59e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define SHA256_CTX sha256_context 60e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#elif (defined(__MAC_OS_X_VERSION_MAX_ALLOWED) && \ 61e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (__MAC_OS_X_VERSION_MAX_ALLOWED >= 1040)) || \ 62e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (defined(__IPHONE_OS_VERSION_MAX_ALLOWED) && \ 63e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (__IPHONE_OS_VERSION_MAX_ALLOWED >= 20000)) 64e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* For Apple operating systems: CommonCrypto has the functions we need. 65e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET The library's headers are even backward-compatible with OpenSSL's 66e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET headers as long as we define COMMON_DIGEST_FOR_OPENSSL first. 67e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 68e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET These functions are available on Tiger and later, as well as iOS 2.0 69e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET and later. If you're building for an older cat, well, sorry. */ 70e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define COMMON_DIGEST_FOR_OPENSSL 71e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <CommonCrypto/CommonDigest.h> 72e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#elif defined(_WIN32) 73e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* For Windows: If no other crypto library is provided, we fallback 74e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET to the hash functions provided within the Microsoft Windows CryptoAPI */ 75e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# include <wincrypt.h> 76e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* Custom structure in order to store the required provider and hash handle */ 77e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstruct win32_crypto_hash { 78e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET HCRYPTPROV hCryptProv; 79e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET HCRYPTHASH hHash; 80e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}; 81e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* Custom Microsoft AES Cryptographic Provider defines required for MinGW */ 82e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# ifndef ALG_SID_SHA_256 83e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define ALG_SID_SHA_256 12 84e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# endif 85e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# ifndef CALG_SHA_256 86e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define CALG_SHA_256 (ALG_CLASS_HASH | ALG_TYPE_ANY | ALG_SID_SHA_256) 87e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# endif 88e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define MD5_CTX struct win32_crypto_hash 89e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define SHA_CTX struct win32_crypto_hash 90e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# define SHA256_CTX struct win32_crypto_hash 91e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#else 92e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET# error "Can't compile METALINK support without a crypto library." 93e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif 94e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 95e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "rawstr.h" 96e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 97e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define ENABLE_CURLX_PRINTF 98e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* use our own printf() functions */ 99e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "curlx.h" 100e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 101e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_getparam.h" 102e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_paramhlp.h" 103e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_cfgable.h" 104e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_metalink.h" 105e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "tool_msgs.h" 106e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 107e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#include "memdebug.h" /* keep this as LAST include */ 108e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 109e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* Copied from tool_getparam.c */ 110e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#define GetStr(str,val) do { \ 111e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(*(str)) { \ 112e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(*(str)); \ 113e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *(str) = NULL; \ 114e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } \ 115e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if((val)) \ 116e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *(str) = strdup((val)); \ 117e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!(val)) \ 118e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return PARAM_NO_MEM; \ 119e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} WHILE_FALSE 120e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 121e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef USE_GNUTLS_NETTLE 122e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 123e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int MD5_Init(MD5_CTX *ctx) 124e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 125e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET md5_init(ctx); 126e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 1; 127e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 128e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 129e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void MD5_Update(MD5_CTX *ctx, 130e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 131e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int inputLen) 132e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 133e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET md5_update(ctx, inputLen, input); 134e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 135e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 136e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) 137e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 138e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET md5_digest(ctx, 16, digest); 139e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 140e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 141e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int SHA1_Init(SHA_CTX *ctx) 142e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 143e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sha1_init(ctx); 144e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 1; 145e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 146e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 147e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA1_Update(SHA_CTX *ctx, 148e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 149e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int inputLen) 150e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 151e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sha1_update(ctx, inputLen, input); 152e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 153e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 154e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx) 155e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 156e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sha1_digest(ctx, 20, digest); 157e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 158e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 159e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int SHA256_Init(SHA256_CTX *ctx) 160e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 161e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sha256_init(ctx); 162e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 1; 163e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 164e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 165e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA256_Update(SHA256_CTX *ctx, 166e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 167e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int inputLen) 168e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 169e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sha256_update(ctx, inputLen, input); 170e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 171e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 172e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx) 173e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 174e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sha256_digest(ctx, 32, digest); 175e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 176e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 177e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#elif defined(USE_GNUTLS) 178e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 179e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int MD5_Init(MD5_CTX *ctx) 180e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 181e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gcry_md_open(ctx, GCRY_MD_MD5, 0); 182e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 1; 183e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 184e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 185e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void MD5_Update(MD5_CTX *ctx, 186e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 187e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int inputLen) 188e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 189e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gcry_md_write(*ctx, input, inputLen); 190e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 191e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 192e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) 193e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 194e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET memcpy(digest, gcry_md_read(*ctx, 0), 16); 195e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gcry_md_close(*ctx); 196e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 197e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 198e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int SHA1_Init(SHA_CTX *ctx) 199e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 200e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gcry_md_open(ctx, GCRY_MD_SHA1, 0); 201e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 1; 202e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 203e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 204e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA1_Update(SHA_CTX *ctx, 205e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 206e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int inputLen) 207e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 208e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gcry_md_write(*ctx, input, inputLen); 209e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 210e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 211e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx) 212e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 213e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET memcpy(digest, gcry_md_read(*ctx, 0), 20); 214e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gcry_md_close(*ctx); 215e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 216e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 217e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int SHA256_Init(SHA256_CTX *ctx) 218e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 219e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gcry_md_open(ctx, GCRY_MD_SHA256, 0); 220e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 1; 221e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 222e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 223e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA256_Update(SHA256_CTX *ctx, 224e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 225e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int inputLen) 226e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 227e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gcry_md_write(*ctx, input, inputLen); 228e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 229e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 230e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx) 231e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 232e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET memcpy(digest, gcry_md_read(*ctx, 0), 32); 233e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET gcry_md_close(*ctx); 234e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 235e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 236e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#elif defined(USE_NSS) 237e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 238e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int nss_hash_init(void **pctx, SECOidTag hash_alg) 239e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 240e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PK11Context *ctx; 241e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 242e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* we have to initialize NSS if not initialized alraedy */ 243e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!NSS_IsInitialized() && !nss_context) { 244e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET static NSSInitParameters params; 245e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET params.length = sizeof params; 246e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET nss_context = NSS_InitContext("", "", "", "", ¶ms, NSS_INIT_READONLY 247e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET | NSS_INIT_NOCERTDB | NSS_INIT_NOMODDB | NSS_INIT_FORCEOPEN 248e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET | NSS_INIT_NOROOTINIT | NSS_INIT_OPTIMIZESPACE | NSS_INIT_PK11RELOAD); 249e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 250e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 251e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ctx = PK11_CreateDigestContext(hash_alg); 252e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!ctx) 253e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return /* failure */ 0; 254e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 255e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(PK11_DigestBegin(ctx) != SECSuccess) { 256e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PK11_DestroyContext(ctx, PR_TRUE); 257e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return /* failure */ 0; 258e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 259e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 260e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *pctx = ctx; 261e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return /* success */ 1; 262e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 263e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 264e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void nss_hash_final(void **pctx, unsigned char *out, unsigned int len) 265e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 266e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PK11Context *ctx = *pctx; 267e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int outlen; 268e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PK11_DigestFinal(ctx, out, &outlen, len); 269e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PK11_DestroyContext(ctx, PR_TRUE); 270e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 271e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 272e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int MD5_Init(MD5_CTX *pctx) 273e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 274e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return nss_hash_init(pctx, SEC_OID_MD5); 275e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 276e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 277e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void MD5_Update(MD5_CTX *pctx, 278e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 279e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int input_len) 280e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 281e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PK11_DigestOp(*pctx, input, input_len); 282e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 283e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 284e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void MD5_Final(unsigned char digest[16], MD5_CTX *pctx) 285e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 286e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET nss_hash_final(pctx, digest, 16); 287e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 288e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 289e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int SHA1_Init(SHA_CTX *pctx) 290e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 291e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return nss_hash_init(pctx, SEC_OID_SHA1); 292e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 293e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 294e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA1_Update(SHA_CTX *pctx, 295e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 296e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int input_len) 297e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 298e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PK11_DigestOp(*pctx, input, input_len); 299e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 300e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 301e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA1_Final(unsigned char digest[20], SHA_CTX *pctx) 302e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 303e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET nss_hash_final(pctx, digest, 20); 304e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 305e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 306e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int SHA256_Init(SHA256_CTX *pctx) 307e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 308e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return nss_hash_init(pctx, SEC_OID_SHA256); 309e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 310e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 311e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA256_Update(SHA256_CTX *pctx, 312e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 313e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int input_len) 314e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 315e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PK11_DigestOp(*pctx, input, input_len); 316e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 317e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 318e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA256_Final(unsigned char digest[32], SHA256_CTX *pctx) 319e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 320e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET nss_hash_final(pctx, digest, 32); 321e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 322e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 323e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#elif defined(USE_POLARSSL) 324e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 325e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int MD5_Init(MD5_CTX *ctx) 326e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 327e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET md5_starts(ctx); 328e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 1; 329e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 330e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 331e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void MD5_Update(MD5_CTX *ctx, 332e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 333e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int inputLen) 334e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 335e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET md5_update(ctx, input, inputLen); 336e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 337e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 338e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) 339e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 340e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET md5_finish(ctx, digest); 341e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 342e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 343e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int SHA1_Init(SHA_CTX *ctx) 344e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 345e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sha1_starts(ctx); 346e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 1; 347e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 348e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 349e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA1_Update(SHA_CTX *ctx, 350e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 351e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int inputLen) 352e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 353e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sha1_update(ctx, input, inputLen); 354e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 355e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 356e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx) 357e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 358e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sha1_finish(ctx, digest); 359e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 360e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 361e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int SHA256_Init(SHA256_CTX *ctx) 362e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 363e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sha256_starts(ctx, 0); /* 0 = sha256 */ 364e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 1; 365e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 366e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 367e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA256_Update(SHA256_CTX *ctx, 368e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 369e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int inputLen) 370e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 371e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sha256_update(ctx, input, inputLen); 372e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 373e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 374e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx) 375e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 376e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sha256_finish(ctx, digest); 377e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 378e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 379e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#elif defined(_WIN32) && !defined(USE_OPENSSL) 380e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 381e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void win32_crypto_final(struct win32_crypto_hash *ctx, 382e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned char *digest, 383e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int digestLen) 384e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 385e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned long length; 386e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CryptGetHashParam(ctx->hHash, HP_HASHVAL, NULL, &length, 0); 387e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(length == digestLen) 388e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CryptGetHashParam(ctx->hHash, HP_HASHVAL, digest, &length, 0); 389e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(ctx->hHash) 390e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CryptDestroyHash(ctx->hHash); 391e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(ctx->hCryptProv) 392e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CryptReleaseContext(ctx->hCryptProv, 0); 393e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 394e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 395e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int MD5_Init(MD5_CTX *ctx) 396e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 397e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, 398e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { 399e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CryptCreateHash(ctx->hCryptProv, CALG_MD5, 0, 0, &ctx->hHash); 400e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 401e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 1; 402e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 403e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 404e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void MD5_Update(MD5_CTX *ctx, 405e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 406e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int inputLen) 407e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 408e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0); 409e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 410e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 411e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void MD5_Final(unsigned char digest[16], MD5_CTX *ctx) 412e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 413e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET win32_crypto_final(ctx, digest, 16); 414e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 415e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 416e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int SHA1_Init(SHA_CTX *ctx) 417e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 418e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, 419e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PROV_RSA_FULL, CRYPT_VERIFYCONTEXT)) { 420e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CryptCreateHash(ctx->hCryptProv, CALG_SHA1, 0, 0, &ctx->hHash); 421e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 422e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 1; 423e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 424e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 425e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA1_Update(SHA_CTX *ctx, 426e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 427e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int inputLen) 428e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 429e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0); 430e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 431e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 432e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA1_Final(unsigned char digest[20], SHA_CTX *ctx) 433e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 434e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET win32_crypto_final(ctx, digest, 20); 435e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 436e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 437e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int SHA256_Init(SHA256_CTX *ctx) 438e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 439e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(CryptAcquireContext(&ctx->hCryptProv, NULL, NULL, 440e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET PROV_RSA_AES, CRYPT_VERIFYCONTEXT)) { 441e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CryptCreateHash(ctx->hCryptProv, CALG_SHA_256, 0, 0, &ctx->hHash); 442e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 443e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 1; 444e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 445e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 446e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA256_Update(SHA256_CTX *ctx, 447e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *input, 448e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int inputLen) 449e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 450e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET CryptHashData(ctx->hHash, (unsigned char *)input, inputLen, 0); 451e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 452e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 453e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void SHA256_Final(unsigned char digest[32], SHA256_CTX *ctx) 454e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 455e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET win32_crypto_final(ctx, digest, 32); 456e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 457e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 458e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif /* CRYPTO LIBS */ 459e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 460e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETconst digest_params MD5_DIGEST_PARAMS[] = { 461e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET { 462e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (Curl_digest_init_func) MD5_Init, 463e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (Curl_digest_update_func) MD5_Update, 464e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (Curl_digest_final_func) MD5_Final, 465e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sizeof(MD5_CTX), 466e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 16 467e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 468e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}; 469e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 470e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETconst digest_params SHA1_DIGEST_PARAMS[] = { 471e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET { 472e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (Curl_digest_init_func) SHA1_Init, 473e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (Curl_digest_update_func) SHA1_Update, 474e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (Curl_digest_final_func) SHA1_Final, 475e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sizeof(SHA_CTX), 476e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 20 477e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 478e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}; 479e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 480e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETconst digest_params SHA256_DIGEST_PARAMS[] = { 481e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET { 482e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (Curl_digest_init_func) SHA256_Init, 483e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (Curl_digest_update_func) SHA256_Update, 484e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (Curl_digest_final_func) SHA256_Final, 485e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET sizeof(SHA256_CTX), 486e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 32 487e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 488e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}; 489e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 490e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic const metalink_digest_def SHA256_DIGEST_DEF[] = { 491e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET {"sha-256", SHA256_DIGEST_PARAMS} 492e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}; 493e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 494e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic const metalink_digest_def SHA1_DIGEST_DEF[] = { 495e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET {"sha-1", SHA1_DIGEST_PARAMS} 496e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}; 497e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 498e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic const metalink_digest_def MD5_DIGEST_DEF[] = { 499e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET {"md5", MD5_DIGEST_PARAMS} 500e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}; 501e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 502e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* 503e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * The alias of supported hash functions in the order by preference 504e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * (basically stronger hash comes first). We included "sha-256" and 505e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * "sha256". The former is the name defined in the IANA registry named 506e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * "Hash Function Textual Names". The latter is widely (and 507e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * historically) used in Metalink version 3. 508e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 509e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic const metalink_digest_alias digest_aliases[] = { 510e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET {"sha-256", SHA256_DIGEST_DEF}, 511e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET {"sha256", SHA256_DIGEST_DEF}, 512e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET {"sha-1", SHA1_DIGEST_DEF}, 513e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET {"sha1", SHA1_DIGEST_DEF}, 514e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET {"md5", MD5_DIGEST_DEF}, 515e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET {NULL, NULL} 516e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET}; 517e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 518e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETdigest_context *Curl_digest_init(const digest_params *dparams) 519e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 520e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET digest_context *ctxt; 521e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 522e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Create digest context */ 523e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ctxt = malloc(sizeof *ctxt); 524e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 525e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!ctxt) 526e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return ctxt; 527e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 528e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ctxt->digest_hashctx = malloc(dparams->digest_ctxtsize); 529e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 530e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!ctxt->digest_hashctx) { 531e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(ctxt); 532e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return NULL; 533e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 534e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 535e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ctxt->digest_hash = dparams; 536e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 537e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(dparams->digest_init(ctxt->digest_hashctx) != 1) { 538e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(ctxt); 539e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return NULL; 540e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 541e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 542e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return ctxt; 543e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 544e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 545e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETint Curl_digest_update(digest_context *context, 546e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *data, 547e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned int len) 548e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 549e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (*context->digest_hash->digest_update)(context->digest_hashctx, data, len); 550e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 551e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 0; 552e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 553e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 554e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETint Curl_digest_final(digest_context *context, unsigned char *result) 555e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 556e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (*context->digest_hash->digest_final)(result, context->digest_hashctx); 557e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 558e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(context->digest_hashctx); 559e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(context); 560e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 561e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 0; 562e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 563e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 564e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic unsigned char hex_to_uint(const char *s) 565e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 566e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int v[2]; 567e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int i; 568e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(i = 0; i < 2; ++i) { 569e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET v[i] = Curl_raw_toupper(s[i]); 570e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if('0' <= v[i] && v[i] <= '9') { 571e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET v[i] -= '0'; 572e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 573e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else if('A' <= v[i] && v[i] <= 'Z') { 574e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET v[i] -= 'A'-10; 575e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 576e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 577e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return (unsigned char)((v[0] << 4) | v[1]); 578e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 579e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 580e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* 581e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Check checksum of file denoted by filename. The expected hash value 582e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * is given in hex_hash which is hex-encoded string. 583e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 584e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * This function returns 1 if it succeeds or one of the following 585e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * integers: 586e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 587e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * 0: 588e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Checksum didn't match. 589e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * -1: 590e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Could not open file; or could not read data from file. 591e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * -2: 592e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Hash algorithm not available. 593e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 594e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int check_hash(const char *filename, 595e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const metalink_digest_def *digest_def, 596e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const unsigned char *digest, FILE *error) 597e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 598e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned char *result; 599e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET digest_context *dctx; 600e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int check_ok, flags, fd; 601e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 602e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET flags = O_RDONLY; 603e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef O_BINARY 604e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* O_BINARY is required in order to avoid binary EOF in text mode */ 605e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET flags |= O_BINARY; 606e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif 607e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 608e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fd = open(filename, flags); 609e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(fd == -1) { 610e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(error, "Metalink: validating (%s) [%s] FAILED (%s)\n", filename, 611e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET digest_def->hash_name, strerror(errno)); 612e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return -1; 613e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 614e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 615e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET dctx = Curl_digest_init(digest_def->dparams); 616e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!dctx) { 617e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(error, "Metalink: validating (%s) [%s] FAILED (%s)\n", filename, 618e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET digest_def->hash_name, "failed to initialize hash algorithm"); 619e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET close(fd); 620e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return -2; 621e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 622e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 623e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET result = malloc(digest_def->dparams->digest_resultlen); 624e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!result) { 625e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET close(fd); 626e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return -1; 627e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 628e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET while(1) { 629e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned char buf[4096]; 630e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ssize_t len = read(fd, buf, sizeof(buf)); 631e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(len == 0) { 632e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 633e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 634e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else if(len == -1) { 635e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(error, "Metalink: validating (%s) [%s] FAILED (%s)\n", filename, 636e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET digest_def->hash_name, strerror(errno)); 637e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_digest_final(dctx, result); 638e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET close(fd); 639e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return -1; 640e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 641e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_digest_update(dctx, buf, (unsigned int)len); 642e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 643e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_digest_final(dctx, result); 644e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET check_ok = memcmp(result, digest, 645e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET digest_def->dparams->digest_resultlen) == 0; 646e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* sha*sum style verdict output */ 647e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(check_ok) 648e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(error, "Metalink: validating (%s) [%s] OK\n", filename, 649e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET digest_def->hash_name); 650e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else 651e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(error, "Metalink: validating (%s) [%s] FAILED (digest mismatch)\n", 652e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET filename, digest_def->hash_name); 653e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 654e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(result); 655e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET close(fd); 656e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return check_ok; 657e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 658e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 659e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETint metalink_check_hash(struct GlobalConfig *config, 660e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalinkfile *mlfile, 661e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const char *filename) 662e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 663e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int rv; 664e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(config->errors, "Metalink: validating (%s)...\n", filename); 665e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(mlfile->checksum == NULL) { 666e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(config->errors, 667e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET "Metalink: validating (%s) FAILED (digest missing)\n", filename); 668e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return -2; 669e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 670e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET rv = check_hash(filename, mlfile->checksum->digest_def, 671e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET mlfile->checksum->digest, config->errors); 672e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return rv; 673e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 674e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 675e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic metalink_checksum *new_metalink_checksum_from_hex_digest 676e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET(const metalink_digest_def *digest_def, const char *hex_digest) 677e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 678e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_checksum *chksum; 679e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET unsigned char *digest; 680e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET size_t i; 681e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET size_t len = strlen(hex_digest); 682e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET digest = malloc(len/2); 683e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!digest) 684e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 0; 685e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 686e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(i = 0; i < len; i += 2) { 687e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET digest[i/2] = hex_to_uint(hex_digest+i); 688e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 689e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET chksum = malloc(sizeof(metalink_checksum)); 690e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(chksum) { 691e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET chksum->digest_def = digest_def; 692e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET chksum->digest = digest; 693e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 694e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return chksum; 695e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 696e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 697e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic metalink_resource *new_metalink_resource(const char *url) 698e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 699e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_resource *res; 700e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET res = malloc(sizeof(metalink_resource)); 701e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(res) { 702e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET res->next = NULL; 703e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET res->url = strdup(url); 704e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!res->url) { 705e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(res); 706e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return NULL; 707e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 708e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 709e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return res; 710e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 711e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 712e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* Returns nonzero if hex_digest is properly formatted; that is each 713e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET letter is in [0-9A-Za-z] and the length of the string equals to the 714e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET result length of digest * 2. */ 715e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int check_hex_digest(const char *hex_digest, 716e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const metalink_digest_def *digest_def) 717e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 718e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET size_t i; 719e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(i = 0; hex_digest[i]; ++i) { 720e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET char c = hex_digest[i]; 721e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!(('0' <= c && c <= '9') || ('a' <= c && c <= 'z') || 722e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ('A' <= c && c <= 'Z'))) { 723e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 0; 724e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 725e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 726e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return digest_def->dparams->digest_resultlen * 2 == i; 727e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 728e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 729e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic metalinkfile *new_metalinkfile(metalink_file_t *fileinfo) 730e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 731e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalinkfile *f; 732e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET f = (metalinkfile*)malloc(sizeof(metalinkfile)); 733e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!f) 734e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return NULL; 735e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 736e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET f->next = NULL; 737e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET f->filename = strdup(fileinfo->name); 738e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!f->filename) { 739e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET free(f); 740e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return NULL; 741e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 742e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET f->checksum = NULL; 743e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET f->resource = NULL; 744e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(fileinfo->checksums) { 745e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const metalink_digest_alias *digest_alias; 746e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(digest_alias = digest_aliases; digest_alias->alias_name; 747e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ++digest_alias) { 748e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_checksum_t **p; 749e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(p = fileinfo->checksums; *p; ++p) { 750e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(Curl_raw_equal(digest_alias->alias_name, (*p)->type) && 751e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET check_hex_digest((*p)->hash, digest_alias->digest_def)) { 752e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET f->checksum = 753e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET new_metalink_checksum_from_hex_digest(digest_alias->digest_def, 754e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (*p)->hash); 755e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 756e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 757e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 758e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(f->checksum) { 759e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 760e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 761e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 762e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 763e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(fileinfo->resources) { 764e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_resource_t **p; 765e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_resource root, *tail; 766e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET root.next = NULL; 767e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET tail = &root; 768e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(p = fileinfo->resources; *p; ++p) { 769e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_resource *res; 770e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Filter by type if it is non-NULL. In Metalink v3, type 771e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET includes the type of the resource. In curl, we are only 772e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET interested in HTTP, HTTPS and FTP. In addition to them, 773e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Metalink v3 file may contain bittorrent type URL, which 774e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET points to the BitTorrent metainfo file. We ignore it here. 775e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET In Metalink v4, type was deprecated and all 776e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fileinfo->resources point to the target file. BitTorrent 777e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metainfo file URL may be appeared in fileinfo->metaurls. 778e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 779e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if((*p)->type == NULL || 780e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_raw_equal((*p)->type, "http") || 781e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_raw_equal((*p)->type, "https") || 782e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_raw_equal((*p)->type, "ftp") || 783e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_raw_equal((*p)->type, "ftps")) { 784e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET res = new_metalink_resource((*p)->url); 785e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET tail->next = res; 786e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET tail = res; 787e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 788e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 789e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET f->resource = root.next; 790e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 791e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return f; 792e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 793e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 794e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETint parse_metalink(struct OperationConfig *config, struct OutStruct *outs, 795e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const char *metalink_url) 796e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 797e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_error_t r; 798e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_t* metalink; 799e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_file_t **files; 800e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET bool warnings = FALSE; 801e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 802e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* metlaink_parse_final deletes outs->metalink_parser */ 803e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET r = metalink_parse_final(outs->metalink_parser, NULL, 0, &metalink); 804e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET outs->metalink_parser = NULL; 805e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(r != 0) { 806e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return -1; 807e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 808e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(metalink->files == NULL) { 809e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(config->global->errors, "Metalink: parsing (%s) WARNING " 810e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET "(missing or invalid file name)\n", 811e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_url); 812e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_delete(metalink); 813e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return -1; 814e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 815e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(files = metalink->files; *files; ++files) { 816e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET struct getout *url; 817e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Skip an entry which has no resource. */ 818e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!(*files)->resources) { 819e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(config->global->errors, "Metalink: parsing (%s) WARNING " 820e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET "(missing or invalid resource)\n", 821e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_url, (*files)->name); 822e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET continue; 823e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 824e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(config->url_get || 825e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET ((config->url_get = config->url_list) != NULL)) { 826e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* there's a node here, if it already is filled-in continue to 827e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET find an "empty" node */ 828e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET while(config->url_get && (config->url_get->flags & GETOUT_URL)) 829e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET config->url_get = config->url_get->next; 830e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 831e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 832e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* now there might or might not be an available node to fill in! */ 833e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 834e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(config->url_get) 835e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* existing node */ 836e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET url = config->url_get; 837e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else 838e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* there was no free node, create one! */ 839e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET url = new_getout(config); 840e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 841e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(url) { 842e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalinkfile *mlfile = new_metalinkfile(*files); 843e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!mlfile) 844e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET break; 845e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 846e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!mlfile->checksum) { 847e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET warnings = TRUE; 848e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(config->global->errors, 849e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET "Metalink: parsing (%s) WARNING (digest missing)\n", 850e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_url); 851e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 852e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* Set name as url */ 853e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET GetStr(&url->url, mlfile->filename); 854e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 855e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* set flag metalink here */ 856e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET url->flags |= GETOUT_URL | GETOUT_METALINK; 857e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 858e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(config->metalinkfile_list) { 859e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET config->metalinkfile_last->next = mlfile; 860e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET config->metalinkfile_last = mlfile; 861e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 862e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else { 863e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET config->metalinkfile_list = config->metalinkfile_last = mlfile; 864e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 865e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 866e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 867e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_delete(metalink); 868e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return (warnings) ? -2 : 0; 869e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 870e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 871e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETsize_t metalink_write_cb(void *buffer, size_t sz, size_t nmemb, 872e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET void *userdata) 873e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 874e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET struct OutStruct *outs = userdata; 875e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET struct OperationConfig *config = outs->config; 876e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int rv; 877e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 878e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET /* 879e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Once that libcurl has called back tool_write_cb() the returned value 880e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * is checked against the amount that was intended to be written, if 881e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * it does not match then it fails with CURLE_WRITE_ERROR. So at this 882e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * point returning a value different from sz*nmemb indicates failure. 883e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 884e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const size_t failure = (sz * nmemb) ? 0 : 1; 885e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 886e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!config) 887e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return failure; 888e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 889e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET rv = metalink_parse_update(outs->metalink_parser, buffer, sz *nmemb); 890e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(rv == 0) 891e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return sz * nmemb; 892e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET else { 893e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET fprintf(config->global->errors, "Metalink: parsing FAILED\n"); 894e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return failure; 895e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 896e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 897e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 898e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET/* 899e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET * Returns nonzero if content_type includes mediatype. 900e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET */ 901e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic int check_content_type(const char *content_type, const char *media_type) 902e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 903e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET const char *ptr = content_type; 904e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET size_t media_type_len = strlen(media_type); 905e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(; *ptr && (*ptr == ' ' || *ptr == '\t'); ++ptr); 906e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(!*ptr) { 907e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return 0; 908e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 909e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return Curl_raw_nequal(ptr, media_type, media_type_len) && 910e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET (*(ptr+media_type_len) == '\0' || *(ptr+media_type_len) == ' ' || 911e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET *(ptr+media_type_len) == '\t' || *(ptr+media_type_len) == ';'); 912e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 913e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 914e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETint check_metalink_content_type(const char *content_type) 915e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 916e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return check_content_type(content_type, "application/metalink+xml"); 917e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 918e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 919e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETint count_next_metalink_resource(metalinkfile *mlfile) 920e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 921e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET int count = 0; 922e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_resource *res; 923e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(res = mlfile->resource; res; res = res->next, ++count); 924e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return count; 925e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 926e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 927e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void delete_metalink_checksum(metalink_checksum *chksum) 928e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 929e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(chksum == NULL) { 930e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return; 931e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 932e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(chksum->digest); 933e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(chksum); 934e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 935e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 936e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void delete_metalink_resource(metalink_resource *res) 937e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 938e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(res == NULL) { 939e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return; 940e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 941e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(res->url); 942e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(res); 943e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 944e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 945e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETstatic void delete_metalinkfile(metalinkfile *mlfile) 946e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 947e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_resource *res; 948e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(mlfile == NULL) { 949e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET return; 950e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 951e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(mlfile->filename); 952e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET delete_metalink_checksum(mlfile->checksum); 953e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET for(res = mlfile->resource; res;) { 954e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalink_resource *next; 955e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET next = res->next; 956e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET delete_metalink_resource(res); 957e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET res = next; 958e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 959e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET Curl_safefree(mlfile); 960e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 961e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 962e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETvoid clean_metalink(struct OperationConfig *config) 963e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 964e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET while(config->metalinkfile_list) { 965e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET metalinkfile *mlfile = config->metalinkfile_list; 966e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET config->metalinkfile_list = config->metalinkfile_list->next; 967e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET delete_metalinkfile(mlfile); 968e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 969e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET config->metalinkfile_last = 0; 970e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 971e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 972e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNETvoid metalink_cleanup(void) 973e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET{ 974e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#ifdef USE_NSS 975e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET if(nss_context) { 976e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET NSS_ShutdownContext(nss_context); 977e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET nss_context = NULL; 978e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET } 979e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif 980e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET} 981e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET 982e6cd738ed3716c02557fb3a47515244e949ade39Bertrand SIMONNET#endif /* USE_METALINK */ 983