/* * s3fs - FUSE-based file system backed by Amazon S3 * * Copyright 2007-2008 Randy Rizun * * This program is free software; you can redistribute it and/or * modify it under the terms of the GNU General Public License * as published by the Free Software Foundation; either version 2 * of the License, or (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. */ #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include "common.h" #include "s3fs_auth.h" using namespace std; //------------------------------------------------------------------- // Utility Function for version //------------------------------------------------------------------- const char* s3fs_crypt_lib_name(void) { static const char version[] = "NSS"; return version; } //------------------------------------------------------------------- // Utility Function for global init //------------------------------------------------------------------- bool s3fs_init_global_ssl(void) { NSS_Init(NULL); NSS_NoDB_Init(NULL); return true; } bool s3fs_destroy_global_ssl(void) { NSS_Shutdown(); PL_ArenaFinish(); PR_Cleanup(); return true; } //------------------------------------------------------------------- // Utility Function for crypt lock //------------------------------------------------------------------- bool s3fs_init_crypt_mutex(void) { return true; } bool s3fs_destroy_crypt_mutex(void) { return true; } //------------------------------------------------------------------- // Utility Function for HMAC //------------------------------------------------------------------- bool s3fs_HMAC(const void* key, size_t keylen, const unsigned char* data, size_t datalen, unsigned char** digest, unsigned int* digestlen) { if(!key || 0 >= keylen || !data || 0 >= datalen || !digest || !digestlen){ return false; } PK11SlotInfo* Slot; PK11SymKey* pKey; PK11Context* Context; SECStatus SecStatus; unsigned char tmpdigest[64]; SECItem KeySecItem = {siBuffer, reinterpret_cast(const_cast(key)), keylen}; SECItem NullSecItem = {siBuffer, NULL, 0}; if(NULL == (Slot = PK11_GetInternalKeySlot())){ return false; } if(NULL == (pKey = PK11_ImportSymKey(Slot, CKM_SHA_1_HMAC, PK11_OriginUnwrap, CKA_SIGN, &KeySecItem, NULL))){ PK11_FreeSlot(Slot); return false; } if(NULL == (Context = PK11_CreateContextBySymKey(CKM_SHA_1_HMAC, CKA_SIGN, pKey, &NullSecItem))){ PK11_FreeSymKey(pKey); PK11_FreeSlot(Slot); return false; } *digestlen = 0; if(SECSuccess != (SecStatus = PK11_DigestBegin(Context)) || SECSuccess != (SecStatus = PK11_DigestOp(Context, data, datalen)) || SECSuccess != (SecStatus = PK11_DigestFinal(Context, tmpdigest, digestlen, sizeof(tmpdigest))) ) { PK11_DestroyContext(Context, PR_TRUE); PK11_FreeSymKey(pKey); PK11_FreeSlot(Slot); return false; } PK11_DestroyContext(Context, PR_TRUE); PK11_FreeSymKey(pKey); PK11_FreeSlot(Slot); if(NULL == (*digest = (unsigned char*)malloc(*digestlen))){ return false; } memcpy(*digest, tmpdigest, *digestlen); return true; } //------------------------------------------------------------------- // Utility Function for MD5 //------------------------------------------------------------------- size_t get_md5_digest_length(void) { return MD5_LENGTH; } unsigned char* s3fs_md5hexsum(int fd, off_t start, ssize_t size) { PK11Context* md5ctx; unsigned char buf[512]; ssize_t bytes; unsigned char* result; unsigned int md5outlen; if(-1 == size){ struct stat st; if(-1 == fstat(fd, &st)){ return NULL; } size = static_cast(st.st_size); } // seek to top of file. if(-1 == lseek(fd, start, SEEK_SET)){ return NULL; } memset(buf, 0, 512); md5ctx = PK11_CreateDigestContext(SEC_OID_MD5); for(ssize_t total = 0; total < size; total += bytes){ bytes = 512 < (size - total) ? 512 : (size - total); bytes = read(fd, buf, bytes); if(0 == bytes){ // end of file break; }else if(-1 == bytes){ // error DPRNNN("file read error(%d)", errno); return NULL; } PK11_DigestOp(md5ctx, buf, bytes); memset(buf, 0, 512); } if(NULL == (result = (unsigned char*)malloc(get_md5_digest_length()))){ PK11_DestroyContext(md5ctx, PR_TRUE); return NULL; } PK11_DigestFinal(md5ctx, result, &md5outlen, get_md5_digest_length()); PK11_DestroyContext(md5ctx, PR_TRUE); if(-1 == lseek(fd, start, SEEK_SET)){ free(result); return NULL; } return result; } /// END