コード例 #1
0
ファイル: pem.c プロジェクト: hyper123/CycloneTCP
error_t pemReadDhParameters(const char_t *input, size_t length, DhParameters *params)
{
   error_t error;
   size_t i;
   size_t j;
   int_t k;
   char_t *buffer;
   const uint8_t *data;
   Asn1Tag tag;

   //Check parameters
   if(input == NULL && length != 0)
      return ERROR_INVALID_PARAMETER;
   if(params == NULL)
      return ERROR_INVALID_PARAMETER;

   //Search for the beginning tag
   k = pemSearchTag(input, length, "-----BEGIN DH PARAMETERS-----", 29);
   //Failed to find the specified tag?
   if(k < 0) return ERROR_INVALID_SYNTAX;

   //Advance the pointer over the tag
   input += k + 29;
   length -= k + 29;

   //Search for the end tag
   k = pemSearchTag(input, length, "-----END DH PARAMETERS-----", 27);
   //Invalid PEM file?
   if(k <= 0) return ERROR_INVALID_SYNTAX;

   //Length of the PEM structure
   length = k;

   //Allocate a memory buffer to hold the decoded data
   buffer = osMemAlloc(length);
   //Failed to allocate memory?
   if(!buffer) return ERROR_OUT_OF_MEMORY;

   //Copy the contents of the PEM structure
   memcpy(buffer, input, length);

   //Remove carriage returns and line feeds
   for(i = 0, j = 0; i < length; i++)
   {
      if(buffer[i] != '\r' && buffer[i] != '\n')
         buffer[j++] = buffer[i];
   }

   //Start of exception handling block
   do
   {
      //The PEM file is Base64 encoded...
      error = base64Decode(buffer, j, buffer, &length);
      //Failed to decode the file?
      if(error) break;

      //Point to the resulting ASN.1 structure
      data = (uint8_t *) buffer;

      //Display ASN.1 structure
      error = asn1DumpObject(data, length, 0);
      //Any error to report?
      if(error) break;

      //The Diffie-Hellman parameters are encapsulated within a sequence
      error = asn1ReadTag(data, length, &tag);
      //Failed to decode ASN.1 tag?
      if(error) break;

      //Enforce encoding, type and class
      error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE);
      //The tag does not match the criteria?
      if(error) break;

      //Point to the first field of the sequence
      data = tag.value;
      length = tag.length;

      //Read the prime modulus
      error = asn1ReadTag(data, length, &tag);
      //Failed to decode ASN.1 tag?
      if(error) break;

      //Enforce encoding, type and class
      error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER);
      //The tag does not match the criteria?
      if(error) break;

      //Convert the prime modulus to a multiple precision integer
      error = mpiReadRaw(&params->p, tag.value, tag.length);
      //Any error to report?
      if(error) break;

      //Point to the next field
      data += tag.totalLength;
      length -= tag.totalLength;

      //Read the generator
      error = asn1ReadTag(data, length, &tag);
      //Failed to decode ASN.1 tag?
      if(error) break;

      //Enforce encoding, type and class
      error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_INTEGER);
      //The tag does not match the criteria?
      if(error) break;

      //Convert the generator to a multiple precision integer
      error = mpiReadRaw(&params->g, tag.value, tag.length);
      //Any error to report?
      if(error) break;

      //Debug message
      TRACE_DEBUG("Diffie-Hellman parameters:\r\n");
      TRACE_DEBUG("  Prime modulus:\r\n");
      TRACE_DEBUG_MPI("    ", &params->p);
      TRACE_DEBUG("  Generator:\r\n");
      TRACE_DEBUG_MPI("    ", &params->g);

      //End of exception handling block
   } while(0);

   //Release previously allocated memory
   osMemFree(buffer);

   //Clean up side effects if necessary
   if(error)
      dhFreeParameters(params);

   //Return status code
   return error;
}
コード例 #2
0
error_t snmpParseMessage(SnmpAgentContext *context, const uint8_t *p, size_t length)
{
   error_t error;
   int32_t version;
   Asn1Tag tag;

   //Debug message
   TRACE_INFO("SNMP message received from %s port %" PRIu16 " (%" PRIuSIZE " bytes)...\r\n",
      ipAddrToString(&context->remoteIpAddr, NULL), context->remotePort, length);

   //Display the contents of the SNMP message
   TRACE_DEBUG_ARRAY("  ", p, length);

   //Dump ASN.1 structure
   error = asn1DumpObject(p, length, 0);
   //Any error to report?
   if(error) return error;

   //The SNMP message is encapsulated within a sequence
   error = asn1ReadTag(p, length, &tag);
   //Failed to decode ASN.1 tag?
   if(error) return error;

   //Enforce encoding, class and type
   error = asn1CheckTag(&tag, TRUE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_SEQUENCE);
   //The tag does not match the criteria?
   if(error) return error;

   //Point to the first field of the sequence
   p = tag.value;
   length = tag.length;

   //Read version identifier
   error = asn1ReadInt32(p, length, &tag, &version);
   //Failed to decode ASN.1 tag?
   if(error) return error;

   //The SNMP agent verifies the version number. If there is a mismatch,
   //it discards the datagram and performs no further actions
   if(version != context->version)
      return ERROR_INVALID_VERSION;

   //Point to the next field
   p += tag.totalLength;
   length -= tag.totalLength;

   //Read SNMP community name
   error = asn1ReadTag(p, length, &tag);
   //Failed to decode ASN.1 tag?
   if(error) return error;

   //Enforce encoding, class and type
   error = asn1CheckTag(&tag, FALSE, ASN1_CLASS_UNIVERSAL, ASN1_TYPE_OCTET_STRING);
   //The tag does not match the criteria?
   if(error) return error;

   //Save community name
   context->request.community = tag.value;
   context->request.communityLen = tag.length;

   //Point to the next field
   p += tag.totalLength;
   length -= tag.totalLength;

   //Read PDU
   error = asn1ReadTag(p, length, &tag);
   //Failed to decode ASN.1 tag?
   if(error) return error;

   //Check encoding
   if(tag.constructed != TRUE)
      return ERROR_WRONG_ENCODING;
   //Enforce class
   if(tag.class != ASN1_CLASS_CONTEXT_SPECIFIC)
      return ERROR_INVALID_CLASS;

   //Save PDU type
   context->request.pduType = (SnmpPduType) tag.type;

   //Process the protocol data unit
   switch(context->request.pduType)
   {
   case SNMP_PDU_GET_REQUEST:
   case SNMP_PDU_GET_NEXT_REQUEST:
      //Parse GetRequest-PDU or GetNextRequest-PDU
      error = snmpParseGetRequestPdu(context, tag.value, tag.length);
      break;
   case SNMP_PDU_GET_BULK_REQUEST:
      //Parse GetBulkRequest-PDU
      error = snmpParseGetBulkRequestPdu(context, tag.value, tag.length);
      break;
   case SNMP_PDU_SET_REQUEST:
      //Parse SetRequest-PDU
      error = snmpParseSetRequestPdu(context, tag.value, tag.length);
      break;
   default:
      //Invalid PDU type
      error = ERROR_INVALID_TYPE;
      break;
   }

   //Failed to parse PDU?
   if(error)
      return error;

   //Format response PDU header
   error = snmpWritePduHeader(context);
   //Any error to report?
   if(error) return error;

   //Debug message
   TRACE_INFO("SNMP message sent (%" PRIuSIZE " bytes)...\r\n", context->response.messageLen);
   //Display the contents of the SNMP message
   TRACE_DEBUG_ARRAY("  ", context->response.message, context->response.messageLen);

   //Display ASN.1 structure
   error = asn1DumpObject(context->response.message, context->response.messageLen, 0);
   //Any error to report?
   if(error) return error;

   //Send SNMP response message
   error = socketSendTo(context->socket, &context->remoteIpAddr, context->remotePort,
      context->response.message, context->response.messageLen, NULL, 0);

   //Return status code
   return error;
}