Important changes to repositories hosted on mbed.com
Mbed hosted mercurial repositories are deprecated and are due to be permanently deleted in July 2026.
To keep a copy of this software download the repository Zip archive or clone locally using Mercurial.
It is also possible to export all your personal repositories from the account settings page.
oid.c
00001 /** 00002 * @file oid.c 00003 * @brief OID (Object Identifier) 00004 * 00005 * @section License 00006 * 00007 * Copyright (C) 2010-2017 Oryx Embedded SARL. All rights reserved. 00008 * 00009 * This file is part of CycloneCrypto Open. 00010 * 00011 * This program is free software; you can redistribute it and/or 00012 * modify it under the terms of the GNU General Public License 00013 * as published by the Free Software Foundation; either version 2 00014 * of the License, or (at your option) any later version. 00015 * 00016 * This program is distributed in the hope that it will be useful, 00017 * but WITHOUT ANY WARRANTY; without even the implied warranty of 00018 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 00019 * GNU General Public License for more details. 00020 * 00021 * You should have received a copy of the GNU General Public License 00022 * along with this program; if not, write to the Free Software Foundation, 00023 * Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. 00024 * 00025 * @author Oryx Embedded SARL (www.oryx-embedded.com) 00026 * @version 1.7.6 00027 **/ 00028 00029 //Switch to the appropriate trace level 00030 #define TRACE_LEVEL CRYPTO_TRACE_LEVEL 00031 00032 //Dependencies 00033 #include <string.h> 00034 #include <ctype.h> 00035 #include "crypto.h" 00036 #include "oid.h" 00037 #include "debug.h" 00038 00039 //Check crypto library configuration 00040 #if (OID_SUPPORT == ENABLED) 00041 00042 00043 /** 00044 * @brief Check whether the specified object identifier is valid 00045 * @param[in] oid Pointer to the object identifier 00046 * @param[in] oidLen Length of the OID, in bytes 00047 * @return Error code 00048 **/ 00049 00050 error_t oidCheck(const uint8_t *oid, size_t oidLen) 00051 { 00052 size_t i; 00053 size_t n; 00054 00055 //Check parameters 00056 if(oid == NULL) 00057 return ERROR_INVALID_PARAMETER; 00058 00059 //Check the length of the OID 00060 if(oidLen == 0) 00061 { 00062 //Report an error 00063 return ERROR_INVALID_SYNTAX; 00064 } 00065 else if(oidLen > 1) 00066 { 00067 //Parse the object identifier 00068 for(i = 1, n = 2; i < oidLen; i++) 00069 { 00070 //Update the total number of nodes 00071 if(!(oid[i] & OID_MORE_FLAG)) 00072 n++; 00073 00074 //SNMP limits object identifier values to a maximum of 128 nodes 00075 if(n > 128) 00076 return ERROR_INVALID_SYNTAX; 00077 } 00078 00079 //Ensure that the last sub-identifier is valid 00080 if(oid[oidLen - 1] & OID_MORE_FLAG) 00081 return ERROR_INVALID_SYNTAX; 00082 } 00083 00084 //The specified OID is valid 00085 return NO_ERROR; 00086 } 00087 00088 00089 /** 00090 * @brief Compare object identifiers 00091 * @param[in] oid1 Pointer the first OID 00092 * @param[in] oidLen1 Length of the first OID, in bytes 00093 * @param[in] oid2 Pointer the second OID 00094 * @param[in] oidLen2 Length of the second OID, in bytes 00095 * @return Comparison result 00096 * @retval 0 Objects identifiers are equal 00097 * @retval -1 The first OID lexicographically precedes the second OID 00098 * @retval 1 The second OID lexicographically precedes the first OID 00099 **/ 00100 00101 int_t oidComp(const uint8_t *oid1, size_t oidLen1, 00102 const uint8_t *oid2, size_t oidLen2) 00103 { 00104 size_t i; 00105 00106 //Perform lexicographical comparison 00107 for(i = 0; i < oidLen1 && i < oidLen2; i++) 00108 { 00109 //Compare current byte 00110 if(oid1[i] < oid2[i]) 00111 return -1; 00112 else if(oid1[i] > oid2[i]) 00113 return 1; 00114 } 00115 00116 //Compare length 00117 if(oidLen1 < oidLen2) 00118 return -1; 00119 else if(oidLen1 > oidLen2) 00120 return 1; 00121 00122 //Object identifiers are equal 00123 return 0; 00124 } 00125 00126 00127 /** 00128 * @brief Encode OID sub-identifier 00129 * @param[in] oid Pointer to the object identifier 00130 * @param[in] maxOidLen Maximum number of bytes the OID can hold 00131 * @param[in,out] pos Offset where to write the sub-identifier 00132 * @param[in] value Value of the sub-identifier 00133 * @return Error code 00134 **/ 00135 00136 error_t oidEncodeSubIdentifier(uint8_t *oid, 00137 size_t maxOidLen, size_t *pos, uint32_t value) 00138 { 00139 size_t i; 00140 size_t n; 00141 uint8_t temp[5]; 00142 00143 //Encode the first byte of the sub-identifier 00144 temp[0] = value & OID_VALUE_MASK; 00145 //Shift the value to the right 00146 value >>= 7; 00147 00148 //Encode the remaining bytes 00149 for(n = 1; value != 0; n++) 00150 { 00151 //Encode current byte 00152 temp[n] = OID_MORE_FLAG | (value & OID_VALUE_MASK); 00153 //Shift the value to the right 00154 value >>= 7; 00155 } 00156 00157 //Sanity check 00158 if((*pos + n) > maxOidLen) 00159 return ERROR_BUFFER_OVERFLOW; 00160 00161 //Write the current sub-identifier 00162 for(i = 0; i < n; i++) 00163 oid[*pos + i] = temp[n - i - 1]; 00164 00165 //Update offset value 00166 *pos += n; 00167 00168 //Successful processing 00169 return NO_ERROR; 00170 } 00171 00172 00173 /** 00174 * @brief Decode OID sub-identifier 00175 * @param[in] oid Pointer to the object identifier 00176 * @param[in] oidLen Length of the OID, in bytes 00177 * @param[in,out] pos Offset where to read the sub-identifier 00178 * @param[out] value Value of the sub-identifier 00179 * @return Error code 00180 **/ 00181 00182 error_t oidDecodeSubIdentifier(const uint8_t *oid, 00183 size_t oidLen, size_t *pos, uint32_t *value) 00184 { 00185 size_t i; 00186 00187 //Initialize the value of the sub-identifier 00188 *value = 0; 00189 00190 //Read the OID until the last byte of the sub-identifier is found 00191 for(i = *pos; i < oidLen; i++) 00192 { 00193 //Shift the value to the left 00194 *value <<= 7; 00195 //Update value of the sub-identifier 00196 *value |= oid[i] & OID_VALUE_MASK; 00197 00198 //Bit b8 is set to zero to indicate the last byte 00199 if(!(oid[i] & OID_MORE_FLAG)) 00200 { 00201 //Update offset value 00202 *pos = i + 1; 00203 //Successful processing 00204 return NO_ERROR; 00205 } 00206 } 00207 00208 //The specified OID is not valid 00209 return ERROR_INVALID_SYNTAX; 00210 } 00211 00212 00213 /** 00214 * @brief Convert a string representation of an OID to a binary OID 00215 * @param[in] str NULL-terminated string representing the OID 00216 * @param[out] oid Object identifier 00217 * @param[in] maxOidLen Maximum number of bytes the OID can hold 00218 * @param[out] oidLen Length of the object identifier 00219 * @return Error code 00220 **/ 00221 00222 error_t oidFromString(const char_t *str, 00223 uint8_t *oid, size_t maxOidLen, size_t *oidLen) 00224 { 00225 error_t error; 00226 size_t i; 00227 size_t j; 00228 size_t n; 00229 uint32_t value; 00230 uint8_t temp[5]; 00231 00232 //Reset the length of the OID 00233 *oidLen = 0; 00234 00235 //Number of nodes 00236 i = 0; 00237 //Initialize the value of the sub-identifier 00238 value = 0; 00239 00240 //Parse input string 00241 while(1) 00242 { 00243 //Digit found? 00244 if(isdigit((uint8_t) *str)) 00245 { 00246 //Update the value of the sub-identifier 00247 value = (value * 10) + (*str - '0'); 00248 } 00249 //Separator or end of string found? 00250 else if(*str == '.' || *str == '\0') 00251 { 00252 //First node? 00253 if(i == 0) 00254 { 00255 //Check value 00256 if(value > 6) 00257 { 00258 //The conversion failed 00259 error = ERROR_INVALID_SYNTAX; 00260 break; 00261 } 00262 00263 //Encode the first sub-identifier 00264 temp[0] = value * 40; 00265 //Prepare to decode the next node 00266 value = 0; 00267 //Do not write current sub-identifier yet 00268 n = 0; 00269 } 00270 //Second node? 00271 else if(i == 1) 00272 { 00273 //Check value 00274 if(value > 39) 00275 { 00276 //The conversion failed 00277 error = ERROR_INVALID_SYNTAX; 00278 break; 00279 } 00280 00281 //Encode the second sub-identifier 00282 temp[0] |= value; 00283 //Prepare to decode the next node 00284 value = 0; 00285 //Write the first two sub-identifiers 00286 n = 1; 00287 } 00288 //Remaining nodes? 00289 else 00290 { 00291 //Encode the first byte of the sub-identifier 00292 temp[0] = value & OID_VALUE_MASK; 00293 //Shift the value to the right 00294 value >>= 7; 00295 00296 //Encode the remaining bytes 00297 for(n = 1; value != 0; n++) 00298 { 00299 //Encode current byte 00300 temp[n] = OID_MORE_FLAG | (value & OID_VALUE_MASK); 00301 //Shift the value to the right 00302 value >>= 7; 00303 } 00304 } 00305 00306 //Sanity check 00307 if(n > maxOidLen) 00308 { 00309 //Report an error 00310 error = ERROR_BUFFER_OVERFLOW; 00311 break; 00312 } 00313 00314 //Write the current sub-identifier 00315 for(j = 0; j < n; j++) 00316 oid[j] = temp[n - j - 1]; 00317 00318 //Advance write pointer 00319 oid += n; 00320 *oidLen += n; 00321 maxOidLen -= n; 00322 00323 //Number of sub-identifiers 00324 i++; 00325 00326 //End of string detected? 00327 if(*str == '\0') 00328 { 00329 //The conversion succeeded 00330 error = NO_ERROR; 00331 break; 00332 } 00333 } 00334 //Invalid character... 00335 else 00336 { 00337 //The conversion failed 00338 error = ERROR_INVALID_SYNTAX; 00339 break; 00340 } 00341 00342 //Point to the next character 00343 str++; 00344 } 00345 00346 //Return status code 00347 return error; 00348 } 00349 00350 00351 /** 00352 * @brief Convert a binary OID to a string representation 00353 * @param[in] oid Object identifier 00354 * @param[in] oidLen Length of the object identifier, in bytes 00355 * @param[out] str NULL-terminated string representing the OID 00356 * @param[in] maxStrLen Maximum length of the resulting string 00357 * @return Pointer to the formatted string 00358 **/ 00359 00360 char_t *oidToString(const uint8_t *oid, 00361 size_t oidLen, char_t *str, size_t maxStrLen) 00362 { 00363 static char_t buffer[64]; 00364 size_t i; 00365 size_t n; 00366 uint32_t value; 00367 char_t *p; 00368 char_t temp[12]; 00369 00370 //The str parameter is optional 00371 if(str == NULL) 00372 { 00373 //Point to the internal buffer 00374 str = buffer; 00375 //Maximum length of the resulting string 00376 maxStrLen = sizeof(buffer) - 1; 00377 } 00378 00379 //Point the beginning of the string 00380 p = str; 00381 //Properly terminate the string 00382 *p = '\0'; 00383 00384 //Check the length of the OID 00385 if(oidLen > 0) 00386 { 00387 //Convert the first 2 bytes 00388 n = sprintf(temp, "%" PRIu8 ".%" PRIu8 "", oid[0] / 40, oid[0] % 40); 00389 00390 //Sanity check 00391 if(n <= maxStrLen) 00392 { 00393 //Copy the resulting string 00394 strcpy(p, temp); 00395 //Advance write pointer 00396 p += n; 00397 maxStrLen -= n; 00398 } 00399 00400 //Initialize the value of the sub-identifier 00401 value = 0; 00402 00403 //Convert the rest of the OID 00404 for(i = 1; i < oidLen; i++) 00405 { 00406 //Shift the value to the left 00407 value <<= 7; 00408 //Update the current value 00409 value |= oid[i] & OID_VALUE_MASK; 00410 00411 //Bit b8 is set to zero to indicate the last byte 00412 if(!(oid[i] & OID_MORE_FLAG)) 00413 { 00414 //Dump current value 00415 n = sprintf(temp, ".%" PRIu32, value); 00416 00417 //Sanity check 00418 if(n <= maxStrLen) 00419 { 00420 //Copy the resulting string 00421 strcpy(p, temp); 00422 //Advance write pointer 00423 p += n; 00424 maxStrLen -= n; 00425 } 00426 00427 //Prepare to decode the next value 00428 value = 0; 00429 } 00430 } 00431 } 00432 00433 //Return a pointer to the formatted string 00434 return str; 00435 } 00436 00437 #endif 00438
Generated on Tue Jul 12 2022 17:10:15 by
1.7.2