OSStatus MicoFlashErase(mico_partition_t partition, uint32_t off_set, uint32_t size) { OSStatus err = kNoErr; uint32_t start_addr = mico_partitions[ partition ].partition_start_addr + off_set; uint32_t end_addr = mico_partitions[ partition ].partition_start_addr + off_set + size - 1; if (size == 0) goto exit; require_action_quiet( partition > MICO_PARTITION_ERROR, exit, err = kParamErr ); require_action_quiet( partition < MICO_PARTITION_MAX, exit, err = kParamErr ); require_action_quiet( mico_partitions[ partition ].partition_owner != MICO_FLASH_NONE, exit, err = kNotFoundErr ); #ifndef BOOTLOADER require_action_quiet( ( mico_partitions[ partition ].partition_options & PAR_OPT_WRITE_MASK ) == PAR_OPT_WRITE_EN, exit, err = kPermissionErr ); #endif require_action_quiet( start_addr >= mico_partitions[ partition ].partition_start_addr, exit, err = kParamErr ); require_action_quiet( end_addr < mico_partitions[ partition ].partition_start_addr + mico_partitions[ partition ].partition_length, exit, err = kParamErr ); if( platform_flash_drivers[ mico_partitions[ partition ].partition_owner ].initialized == false ) { err = MicoFlashInitialize( partition ); require_noerr_quiet( err, exit ); } mico_rtos_lock_mutex( &platform_flash_drivers[ mico_partitions[ partition ].partition_owner ].flash_mutex ); err = platform_flash_erase( &platform_flash_peripherals[ mico_partitions[ partition ].partition_owner ], start_addr, end_addr ); mico_rtos_unlock_mutex( &platform_flash_drivers[ mico_partitions[ partition ].partition_owner ].flash_mutex ); exit: return err; }
/* * Parse a ContentInfo in the context of (i.e., as an element of) * an AuthenticatedSafe. */ static int authSafeElementParse(pkcs12_context * context, const NSS_P7_DecodedContentInfo *info) { p12DecodeLog("authSafeElementParse"); switch(info->type) { case CT_Data: /* unencrypted SafeContents */ require_noerr(safeContentsParse(context, info->content.data), out); break; case CT_EncryptedData: { /* * Decrypt contents to get a SafeContents and * then parse that. */ SecAsn1Item ptext = {0, NULL}; NSS_P7_EncryptedData *edata = info->content.encryptData; require_noerr_quiet(p12Decrypt(context, &edata->contentInfo.encrAlg, &edata->contentInfo.encrContent, &ptext), out); require_noerr(safeContentsParse(context, &ptext), out); break; } default: break; } return 0; out: return -1; }
OSStatus MicoFlashRead( mico_partition_t partition, volatile uint32_t* off_set, uint8_t* outBuffer ,uint32_t inBufferLength) { OSStatus err = kNoErr; uint32_t start_addr = mico_partitions[ partition ].partition_start_addr + *off_set; uint32_t end_addr = mico_partitions[ partition ].partition_start_addr + *off_set + inBufferLength - 1; if (inBufferLength == 0) goto exit; require_action_quiet( partition > MICO_PARTITION_ERROR, exit, err = kParamErr ); require_action_quiet( partition < MICO_PARTITION_MAX, exit, err = kParamErr ); require_action_quiet( mico_partitions[ partition ].partition_owner != MICO_FLASH_NONE, exit, err = kNotFoundErr ); #ifndef BOOTLOADER require_action_quiet( ( mico_partitions[ partition ].partition_options & PAR_OPT_READ_MASK ) == PAR_OPT_READ_EN, exit, err = kPermissionErr ); #endif require_action_quiet( start_addr >= mico_partitions[ partition ].partition_start_addr, exit, err = kParamErr ); require_action_quiet( end_addr < mico_partitions[ partition ].partition_start_addr + mico_partitions[ partition ].partition_length , exit, err = kParamErr ); if( platform_flash_drivers[ mico_partitions[ partition ].partition_owner ].initialized == false ) { err = MicoFlashInitialize( partition ); require_noerr_quiet( err, exit ); } mico_rtos_lock_mutex( &platform_flash_drivers[ mico_partitions[ partition ].partition_owner ].flash_mutex ); err = platform_flash_read( &platform_flash_peripherals[ mico_partitions[ partition ].partition_owner ], &start_addr, outBuffer, inBufferLength ); *off_set = start_addr - mico_partitions[ partition ].partition_start_addr; mico_rtos_unlock_mutex( &platform_flash_drivers[ mico_partitions[ partition ].partition_owner ].flash_mutex ); exit: return err; }
// // Open the directory; initialize the directory handle. // Return FALSE if the directory couldn't be opened. // HXBOOL CMacFindFile::OS_OpenDirectory (const char *dirname) { FSRef dirRef; OSErr err; OS_CloseDirectory(); // in case one was open // open an FSIterator for the supplied directory path #ifdef _MAC_MACHO err = FSRefFromPosixPath(dirname, &dirRef); #else err = FSRefFromHFSPath(dirname, &dirRef); #endif require_noerr_quiet(err, CantGetRefForDirPath); err = FSOpenIterator(&dirRef, kFSIterateFlat, &m_FSIterator); require_noerr(err, CantMakeIterator); return TRUE; CantMakeIterator: CantGetRefForDirPath: return FALSE; }
/* * ShroudedKeyBag parser w/decrypt */ static int shroudedKeyBagParse(pkcs12_context * context, const NSS_P12_SafeBag *safeBag) { p12DecodeLog("Found shrouded key bag"); const NSS_P12_ShroudedKeyBag *keyBag = safeBag->bagValue.shroudedKeyBag; SecAsn1Item ptext = {0, NULL}; require_noerr_quiet(p12Decrypt(context, &keyBag->algorithm, &keyBag->encryptedData, &ptext), out); /* Decode PKCS#8 formatted private key */ NSS_PrivateKeyInfo pki; memset(&pki, 0, sizeof(pki)); require_noerr(decode_item(context, &ptext, kSecAsn1PrivateKeyInfoTemplate, &pki), out); DERItem algorithm = { pki.algorithm.algorithm.Data, pki.algorithm.algorithm.Length }; require(DEROidCompare(&oidRsa, &algorithm), out); CFDataRef keyData = CFDataCreate(kCFAllocatorDefault, pki.privateKey.Data, pki.privateKey.Length); require_noerr(emit_item(context, safeBag->bagAttrs, CFSTR("key"), keyData), out); CFRelease(keyData); return 0; out: return -1; }
OSStatus MicoFlashDisableSecurity( mico_partition_t partition, uint32_t off_set, uint32_t size ) { OSStatus err = kNoErr; uint32_t start_addr = mico_partitions[ partition ].partition_start_addr + off_set; uint32_t end_addr = mico_partitions[ partition ].partition_start_addr + off_set + size - 1; require_action_quiet( partition > MICO_PARTITION_ERROR, exit, err = kParamErr ); require_action_quiet( partition < MICO_PARTITION_MAX, exit, err = kParamErr ); require_action_quiet( mico_partitions[ partition ].partition_owner != MICO_FLASH_NONE, exit, err = kNotFoundErr ); require_action_quiet( start_addr >= mico_partitions[ partition ].partition_start_addr, exit, err = kParamErr ); require_action_quiet( end_addr < mico_partitions[ partition ].partition_start_addr + mico_partitions[ partition ].partition_length, exit, err = kParamErr ); if( platform_flash_drivers[ mico_partitions[ partition ].partition_owner ].initialized == false ) { err = MicoFlashInitialize( partition ); require_noerr_quiet( err, exit ); } mico_rtos_lock_mutex( &platform_flash_drivers[ mico_partitions[ partition ].partition_owner ].flash_mutex ); err = platform_flash_disable_protect( &platform_flash_peripherals[ mico_partitions[ partition ].partition_owner ], start_addr, end_addr); mico_rtos_unlock_mutex( &platform_flash_drivers[ mico_partitions[ partition ].partition_owner ].flash_mutex ); exit: return err; }
static int p12VerifyMac(pkcs12_context * context, const NSS_P12_DecodedPFX *pfx) { NSS_P12_MacData *macData = pfx->macData; require(macData, out); NSS_P7_DigestInfo *digestInfo = &macData->mac; require(digestInfo, out); SecAsn1Item *algOid = &digestInfo->digestAlgorithm.algorithm; require(algOid, out); /* has to be OID_OIW_SHA1 */ DERItem algOidItem = { algOid->Data, algOid->Length }; require(algOidItem.length && DEROidCompare(&oidSha1, &algOidItem), out); uint32_t iterCount = 0; require_noerr_quiet(p12DataToInt(&macData->iterations, &iterCount), out); if (iterCount == 0) { /* optional, default 1 */ iterCount = 1; } /* * In classic fashion, the PKCS12 spec now says: * * When password integrity mode is used to secure a PFX PDU, * an SHA-1 HMAC is computed on the BER-encoding of the contents * of the content field of the authSafe field in the PFX PDU. * * So here we go. */ uint8_t hmac_key[CC_SHA1_DIGEST_LENGTH]; require_noerr_quiet(p12_pbe_gen(context->passphrase, macData->macSalt.Data, macData->macSalt.Length, iterCount, PBE_ID_MAC, hmac_key, sizeof(hmac_key)), out); /* prealloc the mac data */ SecAsn1Item verifyMac; alloc_item(context, &verifyMac, CC_SHA1_DIGEST_LENGTH); SecAsn1Item *ptext = pfx->authSafe.content.data; CCHmac(kCCHmacAlgSHA1, hmac_key, CC_SHA1_DIGEST_LENGTH, ptext->Data, ptext->Length, verifyMac.Data); require_quiet(nssCompareSecAsn1Items(&verifyMac, &digestInfo->digest), out); return 0; out: return -1; }
/* Generate a private/public keypair. */ OSStatus SecKeyGeneratePair(CFDictionaryRef parameters, SecKeyRef *publicKey, SecKeyRef *privateKey) { OSStatus result = errSecUnsupportedAlgorithm; SecKeyRef privKey = NULL; SecKeyRef pubKey = NULL; CFMutableDictionaryRef pubParams = merge_params(parameters, kSecPublicKeyAttrs), privParams = merge_params(parameters, kSecPrivateKeyAttrs); CFStringRef ktype = CFDictionaryGetValue(parameters, kSecAttrKeyType); require(ktype, errOut); if (CFEqual(ktype, kSecAttrKeyTypeEC)) { result = SecECKeyGeneratePair(parameters, &pubKey, &privKey); } else if (CFEqual(ktype, kSecAttrKeyTypeRSA)) { result = SecRSAKeyGeneratePair(parameters, &pubKey, &privKey); } require_noerr(result, errOut); /* Store the keys in the keychain if they are marked as permanent. */ if (getBoolForKey(pubParams, kSecAttrIsPermanent, false)) { require_noerr_quiet(result = add_ref(pubKey, pubParams), errOut); } if (getBoolForKey(privParams, kSecAttrIsPermanent, false)) { require_noerr_quiet(result = add_ref(privKey, privParams), errOut); } if (publicKey) { *publicKey = pubKey; pubKey = NULL; } if (privateKey) { *privateKey = privKey; privKey = NULL; } errOut: CFReleaseSafe(pubParams); CFReleaseSafe(privParams); CFReleaseSafe(pubKey); CFReleaseSafe(privKey); return result; }
p12_error p12decode(pkcs12_context * context, CFDataRef cdpfx) { int err = p12_decodeErr; NSS_P12_DecodedPFX pfx; memset(&pfx, 0, sizeof(pfx)); SecAsn1Item raw_blob = { CFDataGetLength(cdpfx), (void*)CFDataGetBytePtr(cdpfx) }; require_noerr_quiet(decode_item(context, &raw_blob, NSS_P12_DecodedPFXTemplate, &pfx), out); NSS_P7_DecodedContentInfo *dci = &pfx.authSafe; /* only support CT_Data at top level (password based integrity mode) */ require(dci->type == CT_Data, out); require(pfx.macData, out); require_noerr_action_quiet(p12VerifyMac(context, &pfx), out, err = p12_passwordErr); require_noerr_quiet(authSafeParse(context, dci->content.data), out); return errSecSuccess; out: return err; }
SOSCoderStatus SOSCoderResendDH(SOSCoderRef coder, CFErrorRef *error) { if(coder->sessRef == NULL) return kSOSCoderDataReturned; CFMutableDataRef startPacket = CFDataCreateMutable(kCFAllocatorDefault, 0); SOSCoderStatus result = kSOSCoderFailure; require_noerr_quiet(SecOTRSAppendRestartPacket(coder->sessRef, startPacket), exit); secnotice("coder", "Resending OTR Start %@", startPacket); CFRetainAssign(coder->pendingResponse, startPacket); result = kSOSCoderNegotiating; exit: CFReleaseNull(startPacket); return result; }
SecKeyRef SecKeyCreatePublicFromPrivate(SecKeyRef privateKey) { CFDataRef serializedPublic = NULL; SecKeyRef result = NULL; require_noerr_quiet(SecKeyCopyPublicBytes(privateKey, &serializedPublic), fail); require_quiet(serializedPublic, fail); result = SecKeyCreateFromPublicData(kCFAllocatorDefault, SecKeyGetAlgorithmID(privateKey), serializedPublic); fail: CFReleaseSafe(serializedPublic); return result; }
int HTTPScanFHeaderValue( const char *inHeaderPtr, size_t inHeaderLen, const char *inName, const char *inFormat, ... ) { int n; const char * valuePtr; size_t valueLen; va_list args; n = (int) HTTPGetHeaderField( inHeaderPtr, inHeaderLen, inName, NULL, NULL, &valuePtr, &valueLen, NULL ); require_noerr_quiet( n, exit ); va_start( args, inFormat ); n = VSNScanF( valuePtr, valueLen, inFormat, args ); va_end( args ); exit: return( n ); }
static void *securetransport_ssl_thread(void *arg) { OSStatus ortn; int sock = (int)arg; int socket = accept(sock, NULL, NULL); CFArrayRef server_certs = server_chain(); ssl_test_handle * ssl = ssl_test_handle_create(socket, server_certs); SSLContextRef ctx = ssl->st; pthread_setname_np("server thread"); //uint64_t start = mach_absolute_time(); do { ortn = SSLHandshake(ctx); } while (ortn == errSSLWouldBlock); require_noerr_action_quiet(ortn, out, fprintf(stderr, "Fell out of SSLHandshake with error: %d\n", (int)ortn)); //uint64_t elapsed = mach_absolute_time() - start; //fprintf(stderr, "setr elapsed: %lld\n", elapsed); /* SSLProtocol proto = kSSLProtocolUnknown; require_noerr_quiet(SSLGetNegotiatedProtocolVersion(ctx, &proto), out); */ SSLCipherSuite cipherSuite; require_noerr_quiet(ortn = SSLGetNegotiatedCipher(ctx, &cipherSuite), out); //fprintf(stderr, "st negotiated %s\n", sslcipher_itoa(cipherSuite)); out: CFRelease(server_certs); SSLClose(ctx); CFRelease(ctx); if(ssl) { close(ssl->comm); free(ssl); } pthread_exit((void *)(intptr_t)ortn); return NULL; }
/* * Parse an encoded NSS_P12_AuthenticatedSafe */ static int authSafeParse(pkcs12_context * context, const SecAsn1Item *authSafeBlob) { p12DecodeLog("authSafeParse"); NSS_P12_AuthenticatedSafe authSafe; memset(&authSafe, 0, sizeof(authSafe)); require_noerr(decode_item(context, authSafeBlob, NSS_P12_AuthenticatedSafeTemplate, &authSafe), out); unsigned numInfos = nssArraySize((const void **)authSafe.info); unsigned int dex; for (dex=0; dex<numInfos; dex++) { NSS_P7_DecodedContentInfo *info = authSafe.info[dex]; require_noerr_quiet(authSafeElementParse(context, info), out); } return 0; out: return -1; }
static int p12Decrypt(pkcs12_context * context, const SecAsn1AlgId *algId, const SecAsn1Item *cipherText, SecAsn1Item *plainText) { NSS_P12_PBE_Params pbep; // XXX/cs not requiring decoding, but if pbep is uninit this will fail later algIdParse(context, algId, &pbep); CCAlgorithm alg = 0; uint32_t keySizeInBits = 0; uint32_t blockSizeInBytes = 0; // for IV, optional CCOptions options = 0; require_noerr_quiet(pkcsOidToParams(&algId->algorithm, &alg, &keySizeInBits, &blockSizeInBytes, &options), out); uint32_t iterCount = 0; require_noerr(p12DataToInt(&pbep.iterations, &iterCount), out); /* P12 style key derivation */ SecAsn1Item key = {0, NULL}; if(keySizeInBits) alloc_item(context, &key, (keySizeInBits+7)/8); require_noerr(p12_pbe_gen(context->passphrase, pbep.salt.Data, pbep.salt.Length, iterCount, PBE_ID_Key, key.Data, key.Length), out); /* P12 style IV derivation, optional */ SecAsn1Item iv = {0, NULL}; if(blockSizeInBytes) { alloc_item(context, &iv, blockSizeInBytes); require_noerr(p12_pbe_gen(context->passphrase, pbep.salt.Data, pbep.salt.Length, iterCount, PBE_ID_IV, iv.Data, iv.Length), out); } SecAsn1Item ourPtext = {0, NULL}; alloc_item(context, &ourPtext, cipherText->Length); require_noerr(CCCrypt(kCCDecrypt, alg, options/*kCCOptionPKCS7Padding*/, key.Data, key.Length, iv.Data, cipherText->Data, cipherText->Length, ourPtext.Data, ourPtext.Length, &ourPtext.Length), out); *plainText = ourPtext; return 0; out: return -1; }
mDNSBool LsaGetSecret( const char * inDomain, char * outDomain, unsigned outDomainSize, char * outKey, unsigned outKeySize, char * outSecret, unsigned outSecretSize ) { PLSA_UNICODE_STRING domainLSA; PLSA_UNICODE_STRING keyLSA; PLSA_UNICODE_STRING secretLSA; size_t i; size_t dlen; LSA_OBJECT_ATTRIBUTES attrs; LSA_HANDLE handle = NULL; NTSTATUS res; OSStatus err; check( inDomain ); check( outDomain ); check( outKey ); check( outSecret ); // Initialize domainLSA = NULL; keyLSA = NULL; secretLSA = NULL; // Make sure we have enough space to add trailing dot dlen = strlen( inDomain ); err = strcpy_s( outDomain, outDomainSize - 2, inDomain ); require_noerr( err, exit ); // If there isn't a trailing dot, add one because the mDNSResponder // presents names with the trailing dot. if ( outDomain[ dlen - 1 ] != '.' ) { outDomain[ dlen++ ] = '.'; outDomain[ dlen ] = '\0'; } // Canonicalize name by converting to lower case (keychain and some name servers are case sensitive) for ( i = 0; i < dlen; i++ ) { outDomain[i] = (char) tolower( outDomain[i] ); // canonicalize -> lower case } // attrs are reserved, so initialize to zeroes. ZeroMemory( &attrs, sizeof( attrs ) ); // Get a handle to the Policy object on the local system res = LsaOpenPolicy( NULL, &attrs, POLICY_GET_PRIVATE_INFORMATION, &handle ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr( err, exit ); // Get the encrypted data domainLSA = ( PLSA_UNICODE_STRING ) malloc( sizeof( LSA_UNICODE_STRING ) ); require_action( domainLSA != NULL, exit, err = mStatus_NoMemoryErr ); err = MakeLsaStringFromUTF8String( domainLSA, outDomain ); require_noerr( err, exit ); // Retrieve the key res = LsaRetrievePrivateData( handle, domainLSA, &keyLSA ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr_quiet( err, exit ); // <rdar://problem/4192119> Lsa secrets use a flat naming space. Therefore, we will prepend "$" to the keyname to // make sure it doesn't conflict with a zone name. // Strip off the "$" prefix. err = MakeUTF8StringFromLsaString( outKey, outKeySize, keyLSA ); require_noerr( err, exit ); require_action( outKey[0] == '$', exit, err = kUnknownErr ); memcpy( outKey, outKey + 1, strlen( outKey ) ); // Retrieve the secret res = LsaRetrievePrivateData( handle, keyLSA, &secretLSA ); err = translate_errno( res == 0, LsaNtStatusToWinError( res ), kUnknownErr ); require_noerr_quiet( err, exit ); // Convert the secret to UTF8 string err = MakeUTF8StringFromLsaString( outSecret, outSecretSize, secretLSA ); require_noerr( err, exit ); exit: if ( domainLSA != NULL ) { if ( domainLSA->Buffer != NULL ) { free( domainLSA->Buffer ); } free( domainLSA ); } if ( keyLSA != NULL ) { LsaFreeMemory( keyLSA ); } if ( secretLSA != NULL ) { LsaFreeMemory( secretLSA ); } if ( handle ) { LsaClose( handle ); handle = NULL; } return ( !err ) ? TRUE : FALSE; }
void remoteTcpClient_thread(void *inContext) { client_log_trace(); OSStatus err = kUnknownErr; int len; mico_Context_t *Context = inContext; struct sockaddr_t addr; fd_set readfds; fd_set writeSet; char ipstr[16]; struct timeval_t t; int remoteTcpClient_fd = -1; uint8_t *inDataBuffer = NULL; int eventFd = -1; mico_queue_t queue; socket_msg_t *msg; LinkStatusTypeDef wifi_link; int sent_len, errno; mico_rtos_init_semaphore(&_wifiConnected_sem, 1); /* Regisist notifications */ err = MICOAddNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)clientNotify_WifiStatusHandler ); require_noerr( err, exit ); inDataBuffer = malloc(wlanBufferLen); require_action(inDataBuffer, exit, err = kNoMemoryErr); err = micoWlanGetLinkStatus( &wifi_link ); require_noerr( err, exit ); if( wifi_link.is_connected == true ) _wifiConnected = true; while(1) { if(remoteTcpClient_fd == -1 ) { if(_wifiConnected == false){ require_action_quiet(mico_rtos_get_semaphore(&_wifiConnected_sem, 200000) == kNoErr, Continue, err = kTimeoutErr); } err = gethostbyname((char *)Context->flashContentInRam.appConfig.remoteServerDomain, (uint8_t *)ipstr, 16); require_noerr(err, ReConnWithDelay); remoteTcpClient_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); addr.s_ip = inet_addr(ipstr); addr.s_port = Context->flashContentInRam.appConfig.remoteServerPort; err = connect(remoteTcpClient_fd, &addr, sizeof(addr)); require_noerr_quiet(err, ReConnWithDelay); client_log("Remote server connected at port: %d, fd: %d", Context->flashContentInRam.appConfig.remoteServerPort, remoteTcpClient_fd); err = socket_queue_create(Context, &queue); require_noerr( err, exit ); eventFd = mico_create_event_fd(queue); if (eventFd < 0) { client_log("create event fd error"); socket_queue_delete(Context, &queue); goto ReConnWithDelay; } }else{ FD_ZERO(&readfds); FD_SET(remoteTcpClient_fd, &readfds); FD_SET(eventFd, &readfds); FD_ZERO(&writeSet ); FD_SET(remoteTcpClient_fd, &writeSet ); t.tv_sec = 4; t.tv_usec = 0; select(1, &readfds, &writeSet, NULL, &t); /* send UART data */ if ((FD_ISSET( eventFd, &readfds )) && (FD_ISSET(remoteTcpClient_fd, &writeSet ))) {// have data and can write if (kNoErr == mico_rtos_pop_from_queue( &queue, &msg, 0)) { sent_len = write(remoteTcpClient_fd, msg->data, msg->len); if (sent_len <= 0) { len = sizeof(errno); getsockopt(remoteTcpClient_fd, SOL_SOCKET, SO_ERROR, &errno, &len); socket_msg_free(msg); if (errno != ENOMEM) { client_log("write error, fd: %d, errno %d", remoteTcpClient_fd,errno ); goto ReConnWithDelay; } } else { socket_msg_free(msg); } } } /*recv wlan data using remote client fd*/ if (FD_ISSET(remoteTcpClient_fd, &readfds)) { len = recv(remoteTcpClient_fd, inDataBuffer, wlanBufferLen, 0); if(len <= 0) { client_log("Remote client closed, fd: %d", remoteTcpClient_fd); goto ReConnWithDelay; } sppWlanCommandProcess(inDataBuffer, &len, remoteTcpClient_fd, Context); } Continue: continue; ReConnWithDelay: if (eventFd >= 0) { mico_delete_event_fd(eventFd); eventFd = -1; socket_queue_delete(Context, &queue); } if(remoteTcpClient_fd != -1){ SocketClose(&remoteTcpClient_fd); } sleep(CLOUD_RETRY); } } exit: if(inDataBuffer) free(inDataBuffer); client_log("Exit: Remote TCP client exit with err = %d", err); mico_rtos_delete_thread(NULL); return; }
void remoteTcpClient_thread(void *inContext) { client_log_trace(); OSStatus err = kUnknownErr; int len; mico_Context_t *Context = inContext; struct sockaddr_t addr; fd_set readfds; char ipstr[16]; struct timeval_t t; int remoteTcpClient_loopBack_fd = -1; int remoteTcpClient_fd = -1; uint8_t *inDataBuffer = NULL; uint8_t *outDataBuffer = NULL; mico_rtos_init_semaphore(&_wifiConnected_sem, 1); /* Regisist notifications */ err = MICOAddNotification( mico_notify_WIFI_STATUS_CHANGED, (void *)clientNotify_WifiStatusHandler ); require_noerr( err, exit ); inDataBuffer = malloc(wlanBufferLen); require_action(inDataBuffer, exit, err = kNoMemoryErr); outDataBuffer = malloc(wlanBufferLen); require_action(inDataBuffer, exit, err = kNoMemoryErr); /*Loopback fd, recv data from other thread */ remoteTcpClient_loopBack_fd = socket( AF_INET, SOCK_DGRM, IPPROTO_UDP ); require_action(IsValidSocket( remoteTcpClient_loopBack_fd ), exit, err = kNoResourcesErr ); addr.s_ip = IPADDR_LOOPBACK; addr.s_port = REMOTE_TCP_CLIENT_LOOPBACK_PORT; err = bind( remoteTcpClient_loopBack_fd, &addr, sizeof(addr) ); require_noerr( err, exit ); t.tv_sec = 4; t.tv_usec = 0; while(1) { if(remoteTcpClient_fd == -1 ) { if(_wifiConnected == false){ require_action_quiet(mico_rtos_get_semaphore(&_wifiConnected_sem, 200000) == kNoErr, Continue, err = kTimeoutErr); } err = gethostbyname((char *)Context->flashContentInRam.appConfig.remoteServerDomain, (uint8_t *)ipstr, 16); require_noerr(err, ReConnWithDelay); remoteTcpClient_fd = socket(AF_INET, SOCK_STREAM, IPPROTO_TCP); addr.s_ip = inet_addr(ipstr); addr.s_port = Context->flashContentInRam.appConfig.remoteServerPort; err = connect(remoteTcpClient_fd, &addr, sizeof(addr)); require_noerr_quiet(err, ReConnWithDelay); Context->appStatus.isRemoteConnected = true; client_log("Remote server connected at port: %d, fd: %d", Context->flashContentInRam.appConfig.remoteServerPort, remoteTcpClient_fd); }else{ FD_ZERO(&readfds); FD_SET(remoteTcpClient_fd, &readfds); FD_SET(remoteTcpClient_loopBack_fd, &readfds); select(1, &readfds, NULL, NULL, &t); /*recv UART data using loopback fd*/ if (FD_ISSET( remoteTcpClient_loopBack_fd, &readfds) ) { len = recv( remoteTcpClient_loopBack_fd, outDataBuffer, wlanBufferLen, 0 ); SocketSend( remoteTcpClient_fd, outDataBuffer, len ); } /*recv wlan data using remote client fd*/ if (FD_ISSET(remoteTcpClient_fd, &readfds)) { len = recv(remoteTcpClient_fd, inDataBuffer, wlanBufferLen, 0); if(len <= 0) { client_log("Remote client closed, fd: %d", remoteTcpClient_fd); Context->appStatus.isRemoteConnected = false; goto ReConnWithDelay; } sppWlanCommandProcess(inDataBuffer, &len, remoteTcpClient_fd, Context); } Continue: continue; ReConnWithDelay: if(remoteTcpClient_fd != -1){ SocketClose(&remoteTcpClient_fd); } sleep(CLOUD_RETRY); } } exit: if(inDataBuffer) free(inDataBuffer); if(outDataBuffer) free(outDataBuffer); if(remoteTcpClient_loopBack_fd != -1) SocketClose(&remoteTcpClient_loopBack_fd); client_log("Exit: Remote TCP client exit with err = %d", err); mico_rtos_delete_thread(NULL); return; }
static OSStatus SecRSAPublicKeyRawEncrypt(SecKeyRef key, SecPadding padding, const uint8_t *plainText, size_t plainTextLen, uint8_t *cipherText, size_t *cipherTextLen) { OSStatus result = errSecParam; ccrsa_pub_ctx_t pubkey; pubkey.pub = key->key; cc_unit s[ccrsa_ctx_n(pubkey)]; const size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(pubkey), ccrsa_ctx_m(pubkey)); require(cipherTextLen, errOut); require(*cipherTextLen >= m_size, errOut); uint8_t* sBytes = (uint8_t*) s; switch (padding) { case kSecPaddingNone: require_noerr_quiet(ccn_read_uint(ccrsa_ctx_n(pubkey), s, plainTextLen, plainText), errOut); require_quiet(ccn_cmp(ccrsa_ctx_n(pubkey), s, ccrsa_ctx_m(pubkey)) < 0, errOut); break; case kSecPaddingPKCS1: { // Create PKCS1 padding: // // 0x00, 0x01 (RSA_PKCS1_PAD_ENCRYPT), 0xFF .. 0x00, signedData // const int kMinimumPadding = 1 + 1 + 8 + 1; require_quiet(plainTextLen < m_size - kMinimumPadding, errOut); size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(pubkey)) - m_size; while (prefix_zeros--) *sBytes++ = 0x00; size_t pad_size = m_size - plainTextLen; *sBytes++ = 0x00; *sBytes++ = RSA_PKCS1_PAD_ENCRYPT; ccrng_generate(ccrng_seckey, pad_size - 3, sBytes); // Remove zeroes from the random pad const uint8_t* sEndOfPad = sBytes + (pad_size - 3); while (sBytes < sEndOfPad) { if (*sBytes == 0x00) *sBytes = 0xFF; // Michael said 0xFF was good enough. ++sBytes; } *sBytes++ = 0x00; memcpy(sBytes, plainText, plainTextLen); ccn_swap(ccrsa_ctx_n(pubkey), s); break; } case kSecPaddingOAEP: { const struct ccdigest_info* di = ccsha1_di(); const size_t encodingOverhead = 2 + 2 * di->output_size; require_action(m_size > encodingOverhead, errOut, result = errSecParam); require_action_quiet(plainTextLen < m_size - encodingOverhead, errOut, result = errSSLCrypto); require_noerr_action(ccrsa_oaep_encode(di, ccrng_seckey, m_size, s, plainTextLen, plainText), errOut, result = errSecInternal); break; } default: goto errOut; } ccrsa_pub_crypt(pubkey, s, s); ccn_write_uint_padded(ccrsa_ctx_n(pubkey), s, m_size, cipherText); *cipherTextLen = m_size; result = errSecSuccess; errOut: ccn_zero(ccrsa_ctx_n(pubkey), s); return result; }
static OSStatus SecRSAPrivateKeyRawSign(SecKeyRef key, SecPadding padding, const uint8_t *dataToSign, size_t dataToSignLen, uint8_t *sig, size_t *sigLen) { OSStatus result = errSecParam; ccrsa_full_ctx_t fullkey; fullkey.full = key->key; size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey)); cc_unit s[ccrsa_ctx_n(fullkey)]; uint8_t* sBytes = (uint8_t*) s; require(sigLen, errOut); require(*sigLen >= m_size, errOut); switch (padding) { case kSecPaddingNone: require_noerr_quiet(ccn_read_uint(ccrsa_ctx_n(fullkey), s, dataToSignLen, dataToSign), errOut); require_quiet(ccn_cmp(ccrsa_ctx_n(fullkey), s, ccrsa_ctx_m(fullkey)) < 0, errOut); break; case kSecPaddingPKCS1: { // Create PKCS1 padding: // // 0x00, 0x01 (RSA_PKCS1_PAD_SIGN), 0xFF .. 0x00, signedData // const int kMinimumPadding = 1 + 1 + 8 + 1; require(dataToSignLen < m_size - kMinimumPadding, errOut); size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(fullkey)) - m_size; while (prefix_zeros--) *sBytes++ = 0x00; size_t pad_size = m_size - dataToSignLen; *sBytes++ = 0x00; *sBytes++ = RSA_PKCS1_PAD_SIGN; size_t ff_size; for(ff_size = pad_size - 3; ff_size > 0; --ff_size) *sBytes++ = 0xFF; *sBytes++ = 0x00; // Get the user data into s looking like a ccn. memcpy(sBytes, dataToSign, dataToSignLen); ccn_swap(ccrsa_ctx_n(fullkey), s); break; } case kSecPaddingOAEP: result = errSecParam; default: goto errOut; } ccrsa_priv_crypt(ccrsa_ctx_private(fullkey), s, s); // Pad with leading zeros to fit in modulus size ccn_write_uint_padded(ccrsa_ctx_n(fullkey), s, m_size, sig); *sigLen = m_size; result = errSecSuccess; errOut: ccn_zero(ccrsa_ctx_n(fullkey), s); return result; }
void tcp_client_thread(void *inContext) { OSStatus err; struct sockaddr_t addr; struct timeval_t t; fd_set readfds; int tcp_fd = -1 , len; char *buf; buf = (char*)malloc(BUF_LEN); require_action(buf, exit, err = kNoMemoryErr); while(1) { if ( tcp_fd == -1 ) { tcp_fd = socket( AF_INET, SOCK_STREAM, IPPROTO_TCP ); require_action(IsValidSocket( tcp_fd ), exit, err = kNoResourcesErr ); addr.s_ip = inet_addr(tcp_remote_ip); addr.s_port = tcp_remote_port; err = connect(tcp_fd, &addr, sizeof(addr)); require_noerr_quiet(err, ReConnWithDelay); tcp_client_log("Remote server connected at port: %d, fd: %d", addr.s_port, tcp_fd); } else { /*Check status on erery sockets */ FD_ZERO(&readfds); FD_SET(tcp_fd, &readfds); t.tv_sec = 4; t.tv_usec = 0; select(1, &readfds, NULL, NULL, &t); /*recv wlan data using remote client fd*/ if (FD_ISSET( tcp_fd, &readfds )) { len = recv(tcp_fd, buf, BUF_LEN, 0); if( len <= 0) { tcp_client_log("Remote client closed, fd: %d", tcp_fd); goto ReConnWithDelay; } tcp_client_log("[tcp_rec][%d] = %.*s", len, len, buf); sendto(tcp_fd, buf, len, 0, &addr, sizeof(struct sockaddr_t)); } continue; ReConnWithDelay: if(tcp_fd != -1){ SocketClose(&tcp_fd); } tcp_client_log("Connect to %s failed! Reconnect in 5 sec...", tcp_remote_ip); sleep( 5 ); } } exit: mico_rtos_delete_thread(NULL); }
static OSStatus SecRSAPrivateKeyRawDecrypt(SecKeyRef key, SecPadding padding, const uint8_t *cipherText, size_t cipherTextLen, uint8_t *plainText, size_t *plainTextLen) { OSStatus result = errSSLCrypto; ccrsa_full_ctx_t fullkey; fullkey.full = key->key; size_t m_size = ccn_write_uint_size(ccrsa_ctx_n(fullkey), ccrsa_ctx_m(fullkey)); cc_unit s[ccrsa_ctx_n(fullkey)]; uint8_t recoveredData[ccn_sizeof_n(ccrsa_ctx_n(fullkey))]; ccn_read_uint(ccrsa_ctx_n(fullkey), s, cipherTextLen, cipherText); ccrsa_priv_crypt(ccrsa_ctx_private(fullkey), s, s); const uint8_t* sBytes = (uint8_t*) s; const uint8_t* sEnd = (uint8_t*) (s + ccrsa_ctx_n(fullkey)); require(plainTextLen, errOut); switch (padding) { case kSecPaddingNone: ccn_swap(ccrsa_ctx_n(fullkey), s); // Skip Zeros since our contract is to do so. while (sBytes < sEnd && *sBytes == 0x00) ++sBytes; break; case kSecPaddingPKCS1: { ccn_swap(ccrsa_ctx_n(fullkey), s); // Verify and skip PKCS1 padding: // // 0x00, 0x01 (RSA_PKCS1_PAD_ENCRYPT), 0xFF .. 0x00, signedData // size_t prefix_zeros = ccn_sizeof_n(ccrsa_ctx_n(fullkey)) - m_size; while (prefix_zeros--) require_quiet(*sBytes++ == 0x00, errOut); require_quiet(*sBytes++ == 0x00, errOut); require_quiet(*sBytes++ == RSA_PKCS1_PAD_ENCRYPT, errOut); while (*sBytes != 0x00) { require_quiet(++sBytes < sEnd, errOut); } // Required to have at least 8 non-zeros require_quiet((sBytes - (uint8_t*)s) - 2 >= 8, errOut); require_quiet(*sBytes == 0x00, errOut); require_quiet(++sBytes < sEnd, errOut); break; } case kSecPaddingOAEP: { size_t length = sizeof(recoveredData); require_noerr_quiet(ccrsa_oaep_decode(ccsha1_di(), ccn_write_uint_size(ccrsa_ctx_n(fullkey),ccrsa_ctx_m(fullkey)), s, &length, recoveredData), errOut); sBytes = recoveredData; sEnd = recoveredData + length; break; } default: goto errOut; } require((sEnd - sBytes) <= (ptrdiff_t)*plainTextLen, errOut); *plainTextLen = sEnd - sBytes; memcpy(plainText, sBytes, *plainTextLen); result = errSecSuccess; errOut: bzero(recoveredData, sizeof(recoveredData)); ccn_zero(ccrsa_ctx_n(fullkey), s); return result; }