Пример #1
0
/* PUBLIC FUNCTION DEFINITIONS **********************************************/
CsrUint8 getMessageType( WpsBuffer *pIn )
{
    CsrUint8 result = 0;
    WpsBuffer value;

    do
    {
       if( WPS_VERSION != getDataElement( pIn, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "getDataElement(): Version missing" ));
           break;
       }
       if( !checkVersion( &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "checkVersion(): version not supported" ));
           break;
       }
       if( WPS_MESSAGE_TYPE != getDataElement( pIn, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "getDataElement(): Message Type missing" ));
           break;
       }

       /* Everything OK if no break by this point. Finally check the length of the
        * Message Type data element before setting return value */
       if( value.size == 1 )
       {
           result = value.pStart[0];
       }
    }
    while( 0 );

    return result;
}
Пример #2
0
double AverageOnGrid::getGridElement( const unsigned& ipoint, const unsigned& jelement ) const {
  if( noAverage() ) return getDataElement( nper*ipoint + jelement);  

  if( jelement>=(nper-(dimension+1)) ) return getDataElement( nper*ipoint + jelement ); 

  if( noderiv ) return getDataElement( nper*ipoint+jelement ) / getDataElement( nper*(1+ipoint) - 1);

  double rdenom = 1.0; 
  if( fabs(getDataElement( nper*(ipoint+1) -(dimension+1) ))>epsilon ) rdenom = 1. / getDataElement( nper*(ipoint+1) - (dimension+1) );
  
  unsigned jderiv = jelement%(1+dimension);
  if( jderiv==0 ) return rdenom*getDataElement( nper*ipoint+jelement ); 

  unsigned jfloor = std::floor( jelement / (1+dimension) );
  return rdenom*getDataElement( nper*ipoint+jelement ) - rdenom*rdenom*getDataElement(nper*ipoint+jfloor)*getDataElement(nper*(ipoint+1) - (dimension+1) + jderiv); 
}
Пример #3
0
   DataElement* createRasterElement(const char* pName, RasterElementArgs args)
   {
      if (pName == NULL || args.location > 2)
      {
         setLastError(SIMPLE_BAD_PARAMS);
         return NULL;
      }

      // Check for an existing element with the name
      if (getDataElement(pName, TypeConverter::toString<RasterElement>(), 0) != NULL)
      {
         setLastError(SIMPLE_EXISTS);
         return NULL;
      }

      RasterElement* pElement = RasterUtilities::createRasterElement(std::string(pName), args.numRows,
         args.numColumns, args.numBands, static_cast<EncodingTypeEnum>(args.encodingType),
         static_cast<InterleaveFormatTypeEnum>(args.interleaveFormat), args.location != 2, args.pParent);
      if (pElement == NULL)
      {
         switch (args.location)
         {
         case 0:
            pElement = RasterUtilities::createRasterElement(std::string(pName), args.numRows,
               args.numColumns, args.numBands, static_cast<EncodingTypeEnum>(args.encodingType),
               static_cast<InterleaveFormatTypeEnum>(args.interleaveFormat), false, args.pParent);
            if (pElement == NULL)
            {
               setLastError(SIMPLE_OTHER_FAILURE);
               return NULL;
            }
            break;
         case 1:
            setLastError(SIMPLE_NO_MEM);
            return NULL;
         case 2:
            setLastError(SIMPLE_OTHER_FAILURE);
            return NULL;
         default:
            setLastError(SIMPLE_BAD_PARAMS);
            return NULL;
         }
      }
      if (args.pBadValues != NULL && args.numBadValues > 0)
      {
         RasterDataDescriptor* pDesc = static_cast<RasterDataDescriptor*>(pElement->getDataDescriptor());
         if (pDesc != NULL)
         {
            std::vector<int> badValues;
            badValues.reserve(args.numBadValues);
            for (uint32_t idx = 0; idx < args.numBadValues; ++idx)
            {
               badValues.push_back(args.pBadValues[idx]);
            }
            pDesc->setBadValues(badValues);

            // set on the statistics objects
            const std::vector<DimensionDescriptor>& allBands = pDesc->getBands();
            for (std::vector<DimensionDescriptor>::const_iterator band = allBands.begin();
                 band != allBands.end(); ++band)
            {
               if (band->isValid())
               {
                  Statistics* pStats = pElement->getStatistics(*band);
                  if (pStats != NULL)
                  {
                     pStats->setBadValues(badValues);
                  }
               }
            }
            pElement->updateData();
         }
      }

      setLastError(SIMPLE_NO_ERROR);
      return pElement;
   }
Пример #4
0
		static Template parse(const dotX39::Node& node, const std::vector<Ressource>& ressourceList)
		{
			auto tmp = Template();
			tmp.qualifier = node.getName();

#pragma region Argument Parsing
			for (int i = 0; i < node.getArgumentCount(); i++)
			{
				const dotX39::Data* arg = node.getArgument(i);
				if (arg->getName().compare("path") == 0)
				{
					if (arg->getType() != dotX39::DataTypes::STRING)
					{
						std::cerr << std::string("the nodes '").append(tmp.qualifier).append("' 'path' argument should be STRING") << std::endl;
						throw Exceptions::InvalidTypeStructureException();
					}
					tmp.filePath = std::string(Globals::getInstance().basePath.templates).append(static_cast<const dotX39::DataString*>(arg)->getDataAsString());
				}
				else if (arg->getName().compare("fileName") == 0)
				{
					if (arg->getType() != dotX39::DataTypes::STRING)
					{
						std::cerr << std::string("the nodes '").append(tmp.qualifier).append("' 'fileName' argument should be STRING") << std::endl;
						throw Exceptions::InvalidTypeStructureException();
					}
					tmp.outputFileName = std::string(static_cast<const dotX39::DataString*>(arg)->getDataAsString());
				}
				else if (arg->getName().compare("fileExtension") == 0)
				{
					if (arg->getType() != dotX39::DataTypes::STRING)
					{
						std::cerr << std::string("the nodes '").append(tmp.qualifier).append("' 'fileExtension' argument should be STRING") << std::endl;
						throw Exceptions::InvalidTypeStructureException();
					}
					tmp.outputFileExtension = std::string(static_cast<const dotX39::DataString*>(arg)->getDataAsString());
				}
				else 
				{
					if (Globals::getInstance().verbosity)
						std::cout << std::string("the node '").append(tmp.qualifier).append("' contains the unknown argument '").append(arg->getName()).append("', ignored.") << std::endl;
				}
			}
#pragma endregion
#pragma region Data Parsing
			for (int i = 0; i < node.getDataCount(); i++)
			{
				const dotX39::Data* data = node.getData(i);
				if (data->getName().compare("ressources") == 0)
				{
					if (data->getType() != dotX39::DataTypes::ARRAY)
					{
						std::cerr << std::string("the nodes '").append(tmp.qualifier).append("' 'ressources' argument should be ARRAY") << std::endl;
						throw Exceptions::InvalidTypeStructureException();
					}
					auto tmpDataArray = static_cast<const dotX39::DataArray*>(data);
					//We want to validate ALL ressources here so lets create an error counter instead of throwing an exception instantly
					size_t errCount = 0;
					for (int j = 0; j < tmpDataArray->getDataCount(); j++)
					{
						auto data = tmpDataArray->getDataElement(j);
						if (data->getType() != dotX39::DataTypes::STRING)
						{
							std::cerr << std::string("the nodes '").append(tmp.qualifier).append("' 'ressource' argument should be ARRAY with just STRINGs") << std::endl;
							throw Exceptions::InvalidTypeStructureException();
						}
						//Find the ressource in available ressources and push it to the templates ressource list
						bool flag = false;
						auto ressourceName = static_cast<const dotX39::DataString*>(data)->getDataAsString();
						for (auto& it : ressourceList)
						{
							if (it.getQualifier().compare(ressourceName) == 0)
							{
								tmp.ressources.push_back(it);
								flag = true;
								break;
							}
						}
						if (!flag)
						{
							errCount++;
							std::cerr << "Ressource '" << ressourceName << "' is not existing (template: '" << tmp.qualifier << "')" << std::endl;
						}
					}
					//if we did found errors, throw the invalid_argument exception
					if (errCount > 0)
						throw std::invalid_argument("Some Ressources are not existing for a Template");
				}
				else 
				{
					if (Globals::getInstance().verbosity)
						std::cout << std::string("the node '").append(tmp.qualifier).append("' contains the unknown argument '").append(data->getName()).append("', ignored.") << std::endl;
				}
			}
#pragma endregion
#pragma region Node Parsing
			for (int i = 0; i < node.getNodeCount(); i++)
			{
				auto subnode = node.getNode(i);
				if (subnode->getName().compare("templateKeywords") == 0)
				{
					for (int j = 0; j < subnode->getDataCount(); j++)
					{
						auto data = subnode->getData(j);
						if (data->getType() != dotX39::DataTypes::STRING)
						{
							std::cerr << std::string("the nodes '").append(tmp.qualifier).append("' subnodes '").append(subnode->getName()).append("' data datatypes should be STRING") << std::endl;
							throw Exceptions::InvalidTypeStructureException();
						}
						auto templateKeyword = TemplateKeyword::parse(*static_cast<const dotX39::DataString*>(data));
						tmp.keywords.templates.push_back(templateKeyword);
					}
				}
				else if (subnode->getName().compare("replacementKeywords") == 0)
				{
					for (int j = 0; j < subnode->getDataCount(); j++)
					{
						auto data = subnode->getData(j);
						if (data->getType() != dotX39::DataTypes::ARRAY)
						{
							std::cerr << std::string("the nodes '").append(tmp.qualifier).append("' subnodes '").append(subnode->getName()).append("' data datatypes should be ARRAY") << std::endl;
							throw Exceptions::InvalidTypeStructureException();
						}
						tmp.keywords.replacements.push_back(ReplacementKeyword::parse(*static_cast<const dotX39::DataArray*>(data)));
					}
				}
				else
				{
					if (Globals::getInstance().verbosity)
						std::cout << std::string("the node '").append(tmp.qualifier).append("' contains the unknown node '").append(subnode->getName()).append("', ignored.") << std::endl;
				}
			}
#pragma endregion

			if (tmp.filePath.empty())
			{
				std::cerr << std::string("the node '").append(tmp.getQualifier()).append("' has no path argument provided") << std::endl;
				exit(-1);
			}
			std::ifstream stream = std::ifstream(std::string(tmp.filePath).c_str());
			if (!stream.is_open() || !stream.good())
			{
				auto errMsg = std::string("Could not read file: ").append(tmp.filePath);
				std::cerr << errMsg << std::endl;
				throw std::runtime_error(errMsg);
			}
			char s[256];
			while (!stream.eof())
			{
				memset(s, 0, sizeof(s));
				stream.read(s, 255);
				tmp.fileData.append(s);
			}
			stream.close();
			return tmp;
		}
Пример #5
0
CsrBool parseCredential( CsrWpsContext *pCtx, WpsBuffer *pCredential, CsrInt32 credentialCount )
{
    WpsBuffer value;
    CsrUint32 id;
    CsrBool result = FALSE;

    do
    {
       if(WPS_NETWORK_INDEX != getDataElement(pCredential, &value))
       {
           sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: required Network Index missing"));
           break;
       }
       if(WPS_SSID != getDataElement(pCredential, &value))
       {
           sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: required SSID missing"));
           break;
       }

       if(credentialCount != 0 && CsrMemCmp(value.pStart, pCtx->securityContext->setupData.ssid, value.size))
       {
           /* Terminate the parse early successfully if the SSID does not match */
           result = TRUE;
           break;
       }

       sme_trace_info((TR_SECURITY_LIB, "Match found for SSID %s", pCtx->securityContext->setupData.ssid));

       /* Remember the SSID for the final profile generation */
       CsrMemCpy(pCtx->ssid, value.pStart, value.size);

       if(WPS_AUTHENTICATION_TYPE != getDataElement(pCredential, &value))
       {
           sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: required Authentication Type missing"));
           break;
       }

       sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "Authentication type", value.pStart, value.size));
       if(value.size == 2)
       {
           pCtx->authenticationType = value.pStart[0] << 8;
           pCtx->authenticationType |= value.pStart[1];
       }
       else
       {
           sme_trace_info((TR_SECURITY_LIB, "Authentication Type incorrect size"));
           pCtx->authenticationType = 0;
       }

       if(WPS_ENCRYPTION_TYPE != getDataElement(pCredential, &value))
       {
           sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: required Encryption Type missing"));
           break;
       }
       sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "Encryption type", value.pStart, value.size));
       if(value.size == 2)
       {
           pCtx->encryptionType = value.pStart[0] << 8;
           pCtx->encryptionType |= value.pStart[1];
       }
       else
       {
           sme_trace_info((TR_SECURITY_LIB, "Encryption Type incorrect size"));
           pCtx->encryptionType = 0;
       }

       id = getDataElement(pCredential, &value);
       if(WPS_NETWORK_KEY_INDEX != id)
       {
           sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: optional Network Key Index missing"));
           /* Default to network key index 1 */
           pCtx->networkKeyIndex = 1;
       }
       else
       {
           if(value.size == 1 && value.pStart[0] >= 1 && value.pStart[0] <= 4)
           {
               pCtx->networkKeyIndex = value.pStart[0];
           }
           id = getDataElement(pCredential, &value);
       }

       if(WPS_NETWORK_KEY != id)
       {
           sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: required Network Key missing (ignored)"));
           pCtx->networkKeyLength = 0;
       }
       else
       {
           if ((CsrUint16) value.size > sizeof(pCtx->networkKey))
           {
               sme_trace_info((TR_SECURITY_LIB, "Network key too big"));
               break;
           }

           pCtx->networkKeyLength = (CsrUint16) value.size;
           CsrMemCpy(pCtx->networkKey, value.pStart, value.size);

           id = getDataElement(pCredential, &value);
       }

       if(WPS_MAC_ADDRESS != id)
       {
           sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: required MAC Address missing"));
           break;
       }

       /* Check for any optional data elements */
       for(id = getDataElement(pCredential, &value); id != 0; id = getDataElement(pCredential, &value))
       {
           sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: Optional (%04x)", id));
       }

       /* Everything present and correct if no break by this point */
       result = TRUE;
    }
    while(0);

    return result;
}
Пример #6
0
void parseEncryptedSettingsM8(CsrWpsContext *pCtx)
{
    WpsBuffer value;
    CsrUint32 id;
    CsrInt32 credentialCount = 0;
    CsrUint8 digest[WPS_SHA256_DIGEST_LENGTH];

    sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS Encrypted Settings IV", pCtx->encryptedSettings.pStart, WPS_IV_LENGTH));
    sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS Encrypted Settings", &pCtx->encryptedSettings.pStart[WPS_IV_LENGTH], pCtx->encryptedSettings.size - WPS_IV_LENGTH));

    initBuffer(&pCtx->decryptedSettings, (CsrUint8 *)CsrPmalloc(1000), 1000);
    CsrCryptoAes128CbcDecrypt(pCtx->keyWrapKey, pCtx->encryptedSettings.pStart,
                              &pCtx->encryptedSettings.pStart[WPS_IV_LENGTH], pCtx->encryptedSettings.size - WPS_IV_LENGTH,
                              pCtx->decryptedSettings.pStart,
                              &pCtx->decryptedSettings.size,
                              PAD_MODE_PKCS7);
    sme_trace_info((TR_SECURITY_LIB, "Decrypted %d bytes from Encrypted Settings", pCtx->decryptedSettings.size));
    sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS Decrypted Settings", pCtx->decryptedSettings.pStart, pCtx->decryptedSettings.size));

    if(WPS_CREDENTIAL != getDataElement(&pCtx->decryptedSettings, &value))
    {
        sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: required Credential missing"));
        pCtx->result = FALSE;
        freeBuffer(&pCtx->decryptedSettings);
        return;
    }

    if(!parseCredential(pCtx, &value, credentialCount))
    {
        sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: Credential parse bad"));
    }
    credentialCount++;

    /* Check for any non-required optional data elements before final
       Authenticator data element */
    id = getDataElement(&pCtx->decryptedSettings, &value);

    while(WPS_CREDENTIAL == id)
    {
        if(!parseCredential(pCtx, &value, credentialCount))
        {
            sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: Credential parse bad"));
        }
        credentialCount++;
        id = getDataElement(&pCtx->decryptedSettings, &value);
    }

    while(id != 0 && id != WPS_KEY_WRAP_AUTHENTICATOR)
    {
        sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: Non-required optional (%04x)", id));
        id = getDataElement(&pCtx->decryptedSettings, &value);
    }

    if(WPS_KEY_WRAP_AUTHENTICATOR != id)
    {
        sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: Key Wrap Authenticator missing"));
        pCtx->result = FALSE;
        freeBuffer(&pCtx->decryptedSettings);
        return;
    }

    pCtx->rxAuthenticator = value.pStart;

    /* Do not include the 12 byte key wrap authenticator element in the calculation */
    pCtx->decryptedSettings.size -= WPS_TL_LENGTH + WPS_AUTHENTICATOR_LENGTH;

    CsrCryptoHmacSha256(pCtx->authKey, sizeof(pCtx->authKey),
                        pCtx->decryptedSettings.pStart, pCtx->decryptedSettings.size,
                        digest);
    sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS authenticator", digest, WPS_AUTHENTICATOR_LENGTH));

    pCtx->decryptedSettings.size += WPS_TL_LENGTH + WPS_AUTHENTICATOR_LENGTH;

    if(CsrMemCmp(digest, pCtx->rxAuthenticator, WPS_AUTHENTICATOR_LENGTH))
    {
        sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: Key Wrap Authenticator bad"));
        sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS authenticator", pCtx->rxAuthenticator, WPS_AUTHENTICATOR_LENGTH));
        sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS computed authenticator", digest, WPS_AUTHENTICATOR_LENGTH));
        pCtx->result = FALSE;
        freeBuffer(&pCtx->decryptedSettings);
        return;
    }

    /* Everything present and correct if no break by this point */

    pCtx->securityContext->callbacks.wpsDone(pCtx->securityContext->externalContext,
                                             TRUE,
                                             pCtx->authenticationType,
                                             pCtx->encryptionType,
                                             pCtx->networkKey,
                                             pCtx->networkKeyLength,
                                             pCtx->networkKeyIndex,
                                             pCtx->ssid);

    freeBuffer(&pCtx->decryptedSettings);
}
Пример #7
0
void parseM8( CsrWpsContext *pCtx )
{
    WpsBuffer value;
    CsrUint32 id;
    CsrUint8 digest[WPS_SHA256_DIGEST_LENGTH];

    do
    {
        if(WPS_ENROLLEE_NONCE != getDataElement(&pCtx->in, &value))
        {
            sme_trace_info((TR_SECURITY_LIB, "M8: required Enrollee Nonce missing"));
            pCtx->result = FALSE;
            break;
        }
        if(WPS_ENCRYPTED_SETTINGS != getDataElement(&pCtx->in, &pCtx->encryptedSettings))
        {
            sme_trace_info((TR_SECURITY_LIB, "M8: required Encrypted Settings missing"));
            pCtx->result = FALSE;
            break;
        }

        /* Check for any non-required optional data elements before final
           Authenticator data element */
        for( id = getDataElement(&pCtx->in, &value); id != 0 && id != WPS_AUTHENTICATOR; id = getDataElement(&pCtx->in, &value))
        {
            sme_trace_info((TR_SECURITY_LIB, "M8: Non-required optional (%04x)", id));
        }

        if(WPS_AUTHENTICATOR != id)
        {
            sme_trace_info((TR_SECURITY_LIB, "M8: Authenticator missing"));
            pCtx->result = FALSE;
            break;
        }
    }
    while (0);

    if (pCtx->result == FALSE)
    {
        return;
    }

    pCtx->rxAuthenticator = value.pStart;
    /* Do not include the 12 byte authenticator element in the current message */
    /* Compute Authenticator */
    pCtx->in.size -= WPS_TL_LENGTH + WPS_AUTHENTICATOR_LENGTH;
    pCtx->message = (CsrUint8 *)CsrPmalloc(pCtx->out.size + pCtx->in.size);
    CsrMemCpy(pCtx->message, pCtx->out.pStart, pCtx->out.size);
    CsrMemCpy(pCtx->message + pCtx->out.size, pCtx->in.pStart, pCtx->in.size);

    CsrCryptoHmacSha256(pCtx->authKey, sizeof(pCtx->authKey),
                        pCtx->message, pCtx->out.size + pCtx->in.size,
                        digest);
    CsrPfree(pCtx->message);

    sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS authenticator", digest, WPS_AUTHENTICATOR_LENGTH));

    pCtx->in.size += WPS_TL_LENGTH + WPS_AUTHENTICATOR_LENGTH;

    if(CsrMemCmp(pCtx->rxAuthenticator, digest, WPS_AUTHENTICATOR_LENGTH))
    {
        sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS Authenticator error", pCtx->rxAuthenticator, WPS_AUTHENTICATOR_LENGTH));
        sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS computed authenticator", digest, WPS_AUTHENTICATOR_LENGTH));
        sme_trace_info((TR_SECURITY_LIB, "WPS M8 Authenticator BAD"));
        pCtx->result = FALSE;
        return;
    }

    parseEncryptedSettingsM8(pCtx);
    if(pCtx->result == FALSE)
    {
        sme_trace_info((TR_SECURITY_LIB, "WPS Encrypted Settings parse failed"));
    }

    /* Everything present and correct if no break by this point */
}
Пример #8
0
void parseEncryptedSettingsM6(CsrWpsContext *pCtx)
{
    CsrUint8 iv[WPS_IV_LENGTH];
    WpsBuffer value;
    CsrUint32 id;
    CsrUint8 digest[WPS_SHA256_DIGEST_LENGTH];

    sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS Encrypted Settings IV", pCtx->encryptedSettings.pStart, WPS_IV_LENGTH));
    sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS Encrypted Settings", &pCtx->encryptedSettings.pStart[WPS_IV_LENGTH],
                  pCtx->encryptedSettings.size - WPS_IV_LENGTH));

    CsrMemCpy(iv, pCtx->encryptedSettings.pStart, WPS_IV_LENGTH);
    initBuffer(&pCtx->decryptedSettings, (CsrUint8 *)CsrPmalloc(1000), 1000);
    CsrCryptoAes128CbcDecrypt(pCtx->keyWrapKey, iv,
                              &pCtx->encryptedSettings.pStart[WPS_IV_LENGTH], pCtx->encryptedSettings.size - WPS_IV_LENGTH,
                              pCtx->decryptedSettings.pStart,
                              &pCtx->decryptedSettings.size,
                              PAD_MODE_PKCS7);
    sme_trace_info((TR_SECURITY_LIB, "Decrypted %d bytes from Encrypted Settings", pCtx->decryptedSettings.size));
    sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS Decrypted Settings", pCtx->decryptedSettings.pStart, pCtx->decryptedSettings.size));

    if(WPS_R_SNONCE2 != getDataElement( &pCtx->decryptedSettings, &pCtx->rSNonce2))
    {
        sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: required R-SNONCE2 missing"));
        pCtx->result = FALSE;
        freeBuffer(&pCtx->decryptedSettings);
        return;
    }

    /* Check for any non-required optional data elements before final authenticator data element */
    for(id = getDataElement(&pCtx->decryptedSettings, &value); id != 0 && id != WPS_KEY_WRAP_AUTHENTICATOR; id = getDataElement(&pCtx->decryptedSettings, &value))
    {
        sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: Non-required optional (%04x)", id));
    }

    if(WPS_KEY_WRAP_AUTHENTICATOR != id)
    {
        sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: Key Wrap Authenticator missing"));
        pCtx->result = FALSE;
        freeBuffer(&pCtx->decryptedSettings);
        return;
    }

    pCtx->rxAuthenticator = value.pStart;

    /* Do not include the 12 byte key wrap authenticator element in the calculation */
    pCtx->decryptedSettings.size -= WPS_TL_LENGTH + WPS_AUTHENTICATOR_LENGTH;

    CsrCryptoHmacSha256(pCtx->authKey, sizeof(pCtx->authKey),
                        pCtx->decryptedSettings.pStart, pCtx->decryptedSettings.size,
                        digest);

    sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS authenticator", digest, WPS_AUTHENTICATOR_LENGTH));


    pCtx->decryptedSettings.size += WPS_TL_LENGTH + WPS_AUTHENTICATOR_LENGTH;

    if(CsrMemCmp(digest, pCtx->rxAuthenticator, WPS_AUTHENTICATOR_LENGTH))
    {
        sme_trace_info((TR_SECURITY_LIB, "Encrypted Settings Data: Key Wrap Authenticator bad"));
        sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS authenticator", pCtx->rxAuthenticator, WPS_AUTHENTICATOR_LENGTH));
        sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS computed authenticator", digest, WPS_AUTHENTICATOR_LENGTH));
        pCtx->result = FALSE;
        freeBuffer(&pCtx->decryptedSettings);
        return;
    }

    /* The R-SNonce2 is now decoded, so R-HASH2 can be checked */

    /* The E-Hash is the HMAC-SHA256 of the concatenation of a secret
       nonce, PSK, the Enrollee Public Key and the Registrar Public Key,
       keyed with AuthKey. */

    pCtx->message = (CsrUint8 *)CsrPmalloc(2 * WPS_NONCE_LENGTH + sizeof(pCtx->ePubKey) + sizeof(pCtx->rPubKey));
    CsrMemCpy(pCtx->message, pCtx->rSNonce2.pStart, WPS_NONCE_LENGTH);
    CsrMemCpy(pCtx->message + WPS_NONCE_LENGTH, pCtx->psk2, WPS_NONCE_LENGTH);
    CsrMemCpy(pCtx->message + 2 * WPS_NONCE_LENGTH, pCtx->ePubKey, sizeof(pCtx->ePubKey));
    CsrMemCpy(pCtx->message + 2 * WPS_NONCE_LENGTH + sizeof(pCtx->ePubKey), pCtx->rPubKey, sizeof(pCtx->rPubKey));

    CsrCryptoHmacSha256(pCtx->authKey, WPS_SHA256_DIGEST_LENGTH,
                        pCtx->message, 2 * WPS_NONCE_LENGTH + sizeof(pCtx->ePubKey) + sizeof(pCtx->rPubKey),
                        digest);
    CsrPfree(pCtx->message);

    if(CsrMemCmp(digest, pCtx->rHash2, WPS_SHA256_DIGEST_LENGTH))
    {
        sme_trace_info((TR_SECURITY_LIB, "R-HASH2 verification failed"));
        pCtx->result = FALSE;
    }

    freeBuffer(&pCtx->decryptedSettings);

    /* Everything present and correct if no break by this point */
}
Пример #9
0
void parseM2( CsrWpsContext *pCtx )
{
    WpsBuffer value;
    CsrUint32 id;
    CsrBool result = FALSE;
    CsrUint8 digest[WPS_SHA256_DIGEST_LENGTH];

    do
    {
       if( WPS_ENROLLEE_NONCE != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Enrollee Nonce missing" ));
           break;
       }

       if( WPS_REGISTRAR_NONCE != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Registrar Nonce missing" ));
           break;
       }
       /* Check incoming length against expected length? */
       CsrMemCpy( pCtx->rNonce, value.pStart, sizeof( pCtx->rNonce ) );

       if( WPS_UUID_R != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required UUID-R missing" ));
           break;
       }

       if( WPS_PUBLIC_KEY != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Public Key missing" ));
           break;
       }
       /* Check incoming length against expected length? */
       CsrMemCpy( pCtx->rPubKey, value.pStart, sizeof( pCtx->rPubKey ) );

       if( WPS_AUTHENTICATION_TYPE_FLAGS != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Authentication Type Flags missing" ));
           break;
       }

       if( WPS_ENCRYPTION_TYPE_FLAGS != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Encryption Type Flags missing" ));
           break;
       }

       if( WPS_CONNECTION_TYPE_FLAGS != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Connection Type Flags missing" ));
           break;
       }

       if( WPS_CONFIG_METHODS != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Config Methods missing" ));
           break;
       }

       if( WPS_MANUFACTURER != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Manufacturer missing" ));
           break;
       }

       if( WPS_MODEL_NAME != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Model Name missing" ));
           break;
       }

       if( WPS_MODEL_NUMBER != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Model Number missing" ));
           break;
       }

       if( WPS_SERIAL_NUMBER != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Serial Number missing" ));
           break;
       }

       if( WPS_PRIMARY_DEVICE_TYPE != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Primary Device Type missing" ));
           break;
       }

       if( WPS_DEVICE_NAME != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Device Name missing" ));
           break;
       }

       if( WPS_RF_BANDS != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required RF Bands missing" ));
           break;
       }

       if( WPS_ASSOCIATION_STATE != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Association State missing" ));
           break;
       }

       if( WPS_CONFIGURATION_ERROR != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Configuration Error missing" ));
           break;
       }

       if( WPS_DEVICE_PASSWORD_ID != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required Device Password ID missing" ));
           break;
       }

       if( WPS_OS_VERSION_ID != getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: required OS Version ID missing" ));
           break;
       }

       /* Check for any non-required optional data elements before final
          Authenticator data element */
       for( id = getDataElement( &pCtx->in, &value );
            id != 0 && id != WPS_AUTHENTICATOR;
            id = getDataElement( &pCtx->in, &value ) )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: Non-required optional (%04x)", id ));
       }

       if( WPS_AUTHENTICATOR != id )
       {
           sme_trace_info((TR_SECURITY_LIB, "M2: Authenticator missing" ));
           break;
       }

       pCtx->rxAuthenticator = value.pStart;
       result = TRUE;

    } while (0);

    if (result == FALSE)
    {
        pCtx->result = FALSE;
        return;
    }

    computeSessionKeys (pCtx);
    /* Session keys must be derived before AuthKey is used to verify authenticator */
    /* Do not include the 12 byte authenticator element in the current message */
    pCtx->in.size -= WPS_TL_LENGTH + WPS_AUTHENTICATOR_LENGTH;

    pCtx->message = (CsrUint8 *) CsrPmalloc(pCtx->out.size + pCtx->in.size);
    CsrMemCpy(pCtx->message, pCtx->out.pStart, pCtx->out.size);
    CsrMemCpy(pCtx->message + pCtx->out.size, pCtx->in.pStart, pCtx->in.size);

    CsrCryptoHmacSha256(pCtx->authKey, sizeof(pCtx->authKey),
                        pCtx->message, pCtx->out.size + pCtx->in.size,
                        digest);

    CsrPfree(pCtx->message);

    sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS authenticator", digest, WPS_AUTHENTICATOR_LENGTH));

    pCtx->in.size += WPS_TL_LENGTH + WPS_AUTHENTICATOR_LENGTH;

    if(CsrMemCmp(digest, pCtx->rxAuthenticator, WPS_AUTHENTICATOR_LENGTH))
    {
        sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS Authenticator error", pCtx->rxAuthenticator, WPS_AUTHENTICATOR_LENGTH));
        sme_trace_hex((TR_SECURITY_LIB, TR_LVL_INFO, "WPS computed authenticator", digest, WPS_AUTHENTICATOR_LENGTH));
        sme_trace_info((TR_SECURITY_LIB, "WPS M2 Authenticator BAD"));
        pCtx->result = FALSE;
    }
    else
    {
        /* Everything present and correct at this point */
        pCtx->result = TRUE;
    }
}