diff --git a/src/omv/py/py_winc.c b/src/omv/py/py_winc.c index b72d9c89b..01097eda2 100644 --- a/src/omv/py/py_winc.c +++ b/src/omv/py/py_winc.c @@ -799,7 +799,7 @@ static mp_obj_t winc_fw_dump(mp_obj_t self_in) static mp_obj_t winc_fw_update(mp_obj_t self_in) { // Erase the WINC1500 flash. - printf("Erasing WINC's flash...\n"); + printf("Erasing flash...\n"); if (programmer_erase_all() != M2M_SUCCESS) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Failed to erase entire flash!")); } @@ -811,23 +811,11 @@ static mp_obj_t winc_fw_update(mp_obj_t self_in) } // Verify the firmware on the WINC1500 flash. - printf("Verifying firmware image from flash...\n"); + printf("Verifying firmware image...\n"); if (verify_firmware() != M2M_SUCCESS) { nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Failed to verify firmware section!")); } - // Program the certificates on the WINC1500 flash. - printf("Programming certificates...\n"); - if (burn_certificates() != M2M_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Error while writing certificates!")); - } - - // Verify the certificates on the WINC1500 flash. - printf("Reading certificates from flash...\n"); - if (verify_certificates() != M2M_SUCCESS) { - nlr_raise(mp_obj_new_exception_msg(&mp_type_OSError, "Failed to dump certificate section!")); - } - printf("All task completed successfully.\n"); return mp_const_none; } diff --git a/src/winc1500/include/programmer/programmer.h b/src/winc1500/include/programmer/programmer.h index 9c52cd5d4..f55ad50c5 100644 --- a/src/winc1500/include/programmer/programmer.h +++ b/src/winc1500/include/programmer/programmer.h @@ -57,6 +57,4 @@ int burn_firmware(void); int verify_firmware(void); int dump_firmware(void); -int burn_certificates(void); -int verify_certificates(void); #endif /* IMAGE_DOWNLOADER_H_INCLUDED */ diff --git a/src/winc1500/include/root_cert/root_setup.h b/src/winc1500/include/root_cert/root_setup.h deleted file mode 100644 index c9d0ed34c..000000000 --- a/src/winc1500/include/root_cert/root_setup.h +++ /dev/null @@ -1,49 +0,0 @@ -/** - * - * \file - * - * \brief Root Certificate Setup. - * - * Copyright (c) 2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -#ifndef ROOT_CERT_SETUP_H_INCLUDED -#define ROOT_CERT_SETUP_H_INCLUDED - -#include "programmer/programmer.h" - -int WriteRootCertificate(const char *filename, char *pcRootCertFileData, uint32 u32FileSize); - -#endif /* ROOT_CERT_SETUP_H_INCLUDED */ diff --git a/src/winc1500/include/root_cert/x509/asn1.h b/src/winc1500/include/root_cert/x509/asn1.h deleted file mode 100644 index 3d3846e0c..000000000 --- a/src/winc1500/include/root_cert/x509/asn1.h +++ /dev/null @@ -1,84 +0,0 @@ -/** - * - * \file - * - * \brief ASN1. - * - * Copyright (c) 2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -#ifndef ASN1_H_INCLUDED -#define ASN1_H_INCLUDED - -#include "common/include/nm_common.h" - -/* ASN.1 TAG DEFINITIONS. */ -#define ASN1_INVALID 0x00 -#define ASN1_BOOLEAN 0x01 -#define ASN1_INTEGER 0x02 -#define ASN1_BIT_STRING 0x03 -#define ASN1_OCTET_STRING 0x04 -#define ASN1_NULL 0x05 -#define ASN1_OBJECT_IDENTIFIER 0x06 -#define ASN1_UTF8_DTRING 0x0C -#define ASN1_PRINTABLE_STRING 0x13 -#define ASN1_TELETEX_STRING 0x14 -#define ASN1_UTC_TIME 0x17 -#define ASN1_GENERALIZED_TIME 0x18 -#define ASN1_SEQUENCE 0x30 -#define ASN1_SET 0x31 - -#define ASN1_SUCCESS 0 - -#define ASN1_FAIL -1 - -typedef struct { - uint8 *pu8Buff; - uint8 *pu8Data; - uint16 u16BuffLen; -} tstrAsn1Context; - -typedef struct { - uint32 u32Length; - uint8 u8Tag; -} tstrAsn1Element; - -uint16 ASN1_GetNextElement(tstrAsn1Context *pstrAsn1Ctxt, tstrAsn1Element *pstrElement); - -uint16 ASN1_Read(tstrAsn1Context *pstrAsn1Cxt, uint32 u32ReadLength, uint8 *pu8ReadBuffer); - -uint16 ASN1_ReadReference(tstrAsn1Context *pstrAsn1Cxt, uint32 u32ReadLength, uint8 **ppu8ReadBuffer); - -#endif /* ASN1_H_INCLUDED */ diff --git a/src/winc1500/include/root_cert/x509/common.h b/src/winc1500/include/root_cert/x509/common.h deleted file mode 100644 index 4bbe398fc..000000000 --- a/src/winc1500/include/root_cert/x509/common.h +++ /dev/null @@ -1,101 +0,0 @@ -/** - * - * \file - * - * \brief Common Functions. - * - * Copyright (c) 2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -#ifndef COMMON_H_INCLUDED -#define COMMON_H_INCLUDED - -#include "common/include/nm_common.h" -#include -#ifdef WIN32 -#include -#endif - -typedef struct { - uint16 u16BufferSize; - uint8 *pu8Data; -} tstrBuffer; - -/* Used for time storage. */ -typedef struct { - uint16 u16Year; - uint8 u8Month; - uint8 u8Day; - uint8 u8Hour; - uint8 u8Minute; - uint8 u8Second; -} tstrSystemTime; - -#define SIZE_128_BITS (16) -#define SIZE_256_BITS (32) -#define SIZE_512_BITS (64) -#define SIZE_1024_BITS (128) -#define SIZE_1536_BITS (192) -#define SIZE_2048_BITS (256) - -#define GETU16(BUF, OFFSET) ((((uint16)((BUF)[OFFSET]) << 8)) | (((uint16)(BUF)[OFFSET + 1]))) - -/*!< Retrieve 2 bytes from the given buffer at the given - * offset as 16-bit unsigned integer in the Network byte order. - */ - -#define GETU32(BUF,OFFSET) ((((uint32)((BUF)[OFFSET]) << 24)) | (((uint32)((BUF)[OFFSET + 1]) << 16)) | \ - (((uint32)((BUF)[OFFSET + 2]) << 8)) | ((uint32)((BUF)[OFFSET + 3]))) -/*!< Retrieve 4 bytes from the given buffer at the given - offset as 32-bit unsigned integer in the Network byte order. -*/ - -#define PUTU32(VAL32, BUF, OFFSET) \ - do \ - { \ - (BUF)[OFFSET ] = BYTE_3((VAL32)); \ - (BUF)[OFFSET + 1 ] = BYTE_2((VAL32)); \ - (BUF)[OFFSET + 2 ] = BYTE_1((VAL32)); \ - (BUF)[OFFSET + 3 ] = BYTE_0((VAL32)); \ - } while (0) - -#define PUTU16(VAL16, BUF, OFFSET) \ - do \ - { \ - (BUF)[OFFSET ] = BYTE_1((VAL16)); \ - (BUF)[OFFSET + 1 ] = BYTE_0((VAL16)); \ - } while (0) - -#endif /* COMMON_H_INCLUDED */ diff --git a/src/winc1500/include/root_cert/x509/hash.h b/src/winc1500/include/root_cert/x509/hash.h deleted file mode 100644 index 1dfbbd457..000000000 --- a/src/winc1500/include/root_cert/x509/hash.h +++ /dev/null @@ -1,112 +0,0 @@ -/** - * - * \file - * - * \brief Hash Functions. - * - * Copyright (c) 2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -#ifndef HASH_H_INCLUDED -#define HASH_H_INCLUDED - -#include "common.h" - -#define SHA_BLOCK_SIZE 64 - -#define MD5_DIGEST_SIZE (16) -#define SHA1_DIGEST_SIZE (20) -#define SHA256_DIGEST_SIZE 32 - -#define SHA_MAX_DIGEST_SIZE SHA256_DIGEST_SIZE - -#define SHA_FLAGS_INIT 0x01 - -/*!< A flag to tell the hash function to - * start hash from the initial state. - */ - -#define SHA_FLAGS_UPDATE 0x02 - -/*!< Update the current hash with the - * given data. - */ - -#define SHA_FLAGS_FINISH 0x04 - -/*!< Finalize the hashing and calculate - * the final result. - */ - -#define SHA_FLAGS_FULL_HASH (SHA_FLAGS_INIT | SHA_FLAGS_UPDATE | SHA_FLAGS_FINISH) - -#define SHA1_INIT(ctxt) SHA1_Hash((ctxt), SHA_FLAGS_INIT, NULL, 0, NULL) -#define SHA1_UPDATE(ctxt, data, dataLen) SHA1_Hash((ctxt), SHA_FLAGS_UPDATE, (data), (dataLen), NULL) -#define SHA1_FINISH(ctxt, digest) SHA1_Hash((ctxt), SHA_FLAGS_FINISH, NULL, 0, digest) - -#define MD5_INIT(ctxt) MD5_Hash((ctxt), SHA_FLAGS_INIT, NULL, 0, NULL) -#define MD5_UPDATE(ctxt, data, dataLen) MD5_Hash((ctxt), SHA_FLAGS_UPDATE, (data), (dataLen), NULL) -#define MD5_FINISH(ctxt, digest) MD5_Hash((ctxt), SHA_FLAGS_FINISH, NULL, 0, digest) - -typedef void (*tpfHashProcessBlock)(uint32 *pu32HashState, const uint8 *pu8MessageBlock); - -typedef struct { - uint32 au32HashState[SHA_MAX_DIGEST_SIZE / 4]; - uint8 au8CurrentBlock[SHA_BLOCK_SIZE]; - uint32 u32TotalLength; - tpfHashProcessBlock fpHash; - uint8 u8BlockSize; - uint8 u8DigestSize; -} tstrHashContext; - -typedef tstrHashContext tstrMd5Context; -typedef tstrHashContext tstrSha1Context; -typedef tstrHashContext tstrSha256Context; - -typedef void (*tpfHash) -( - tstrHashContext *pstrHashContext, - uint8 u8Flags, - uint8 *pu8Data, - uint32 u32DataLength, - uint8 *pu8Digest -); - -void MD5_Hash(tstrHashContext *pstrMD5Context, uint8 u8Flags, uint8 *pu8Data, uint32 u32DataLength, uint8 *pu8Digest); -void HMAC_Vector(tpfHash fpHash, uint8 *pu8Key, uint32 u32KeyLength, tstrBuffer *pstrInData, uint8 u8NumInputs, uint8 *pu8Out); -void SHA1_Hash(tstrHashContext *pstrSha1Context, uint8 u8Flags, uint8 *pu8Data, uint32 u32DataLength, uint8 *pu8Digest); -void SHA256_Hash(tstrHashContext *pstrSha256Context, uint8 u8Flags, uint8 *pu8Data, uint32 u32DataLength, uint8 *pu8Digest); - -#endif /* HASH_H_INCLUDED */ diff --git a/src/winc1500/include/root_cert/x509/x509_cert.h b/src/winc1500/include/root_cert/x509/x509_cert.h deleted file mode 100644 index 1e738f145..000000000 --- a/src/winc1500/include/root_cert/x509/x509_cert.h +++ /dev/null @@ -1,177 +0,0 @@ -/** - * - * \file - * - * \brief X509 Certificate Functions. - * - * Copyright (c) 2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -#ifndef X509_CERT_H_INCLUDED -#define X509_CERT_H_INCLUDED - -#include "common.h" -#include "hash.h" - -#define X509_SUCCESS 0 -#define X509_FAIL -1 - -#define X509_SERIAL_NO_MAX_LENGTH 20 - -/* X509 ALGORITHMS. */ -#define X509_ALG_NULL 0 -#define X509_PUB_RSA 1 -#define X509_SIGN_MD5RSA 2 -#define X509_SIGN_SHA1RSA 3 -#define X509_SIGN_SHA256RSA 4 -#define X509_SIGN_SHA384RSA 5 -#define X509_SIGN_SHA512RSA 6 - -#define X509_STATUS_VALID 0 -/*!< - * The X.509 certificate is valid. - */ - -#define X509_STATUS_EXPIRED 1 -/*!< - * The X.509 certificate is expired. - */ - -#define X509_STATUS_REVOKED 2 -/*!< - * The X.509 certificate is marked as revoked and should not - * be trusted. - */ - -#define X509_STATUS_DECODE_ERR 4 -/*!< - * Error decoding the certificate time. - */ - -#define X509_CERT_DUMP X509Cert_Dump -#define X509_CERT_IS_VALID X509Cert_IsValid - -typedef enum { - PUBKEY_ALG_RSA, - PUBKEY_ALG_DH, - PUBKEY_ALG_ECDH -} tenuPubKeyAlg; - -typedef enum { - SIGN_VERIFY, - SIGN_GEN -} tenuSignMode; - -/*! - * @struct tstrDHPublicKey - * - * @brief Diffie-Hellman Public Key Definition - */ -typedef struct { - uint8 *pu8P; - uint8 *pu8G; - uint8 *pu8Key; - uint16 u16PSize; - uint16 u16GSize; - uint16 u16KeySize; -} tstrDHPublicKey; - -/*! - * @struct tstrRSAPublicKey - * - * @brief RSA Public Key Definition - */ -typedef struct { - uint16 u16NSize; - uint16 u16ESize; - uint8 *pu8N; - uint8 *pu8E; -} tstrRSAPublicKey; - -typedef struct { - tenuPubKeyAlg enuType; - union { - tstrRSAPublicKey strRSAKey; - tstrDHPublicKey strDHKey; - }; -} tstrPublicKey; - -typedef struct { - char acCmnName[65]; - char acOrg[65]; - char acOrgUnit[65]; - uint8 au8NameSHA1[SHA1_DIGEST_SIZE]; -} tstrX520Name; - -typedef struct { - uint8 au8Time[20]; -} tstrX509Time; - -typedef struct { - uint8 u8Version; - /*!< - * X509 version. - */ - - uint8 u8SerialNumberLength; - /*!< - * X509 certificate serial number Length in bytes. - */ - - uint8 au8SerialNo[X509_SERIAL_NO_MAX_LENGTH]; - /*!< - * X509 certificate serial number. - */ - - uint8 u8SignAlg; - /*!< - * X509 certificate serial number Length in bytes. - */ - - uint8 u8ValidityStatus; - tstrX520Name strIssuer; - tstrX509Time strStartDate; - tstrX509Time strExpiryDate; - tstrX520Name strSubject; - tstrPublicKey strPubKey; - tstrBuffer strSignature; - uint8 *pu8TBSCert; - uint16 u16TBSCertSize; -} tstrX509Cert; - -sint8 X509Cert_Decode(uint8 *pu8X509Buffer, uint32 u32CertSize, tstrX509Cert *pstrCert, uint8 bDumpX509); -void X509Cert_Dump(void *pvCert); - -#endif /* X509_CERT_H_INCLUDED */ diff --git a/src/winc1500/src/asn1.c b/src/winc1500/src/asn1.c deleted file mode 100644 index d1febaa12..000000000 --- a/src/winc1500/src/asn1.c +++ /dev/null @@ -1,120 +0,0 @@ -/** - * - * \file - * - * \brief ASN1. - * - * Copyright (c) 2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -#include "root_cert/x509/asn1.h" - -uint16 ASN1_GetNextElement(tstrAsn1Context *pstrAsn1Ctxt, tstrAsn1Element *pstrElement) -{ - uint16 u16ElemLength = 0; - - if ((pstrElement != NULL) && (pstrAsn1Ctxt != NULL)) { - uint8 u8NLenBytes; - - do { - u8NLenBytes = 0; - - /* Get the ASN.1 Element Tag. */ - pstrElement->u8Tag = *pstrAsn1Ctxt->pu8Data++; - - /* Get the ASN.1 element length. */ - pstrElement->u32Length = *pstrAsn1Ctxt->pu8Data++; - pstrElement->u32Length &= 0xFF; - if (pstrElement->u32Length & NBIT7) { - uint8 u8Idx; - uint8 au8Tmp[4]; - - /* Multiple Length octets. */ - u8NLenBytes = (uint8)(pstrElement->u32Length & 0x03); - pstrElement->u32Length = 0; - - m2m_memcpy(au8Tmp, pstrAsn1Ctxt->pu8Data, u8NLenBytes); - pstrAsn1Ctxt->pu8Data += u8NLenBytes; - - for (u8Idx = 0; u8Idx < u8NLenBytes; u8Idx++) { - pstrElement->u32Length += - (uint32)(au8Tmp[u8Idx] << ((u8NLenBytes - u8Idx - 1) * 8)); - } - } - - u16ElemLength += u8NLenBytes + 2 + (uint16)pstrElement->u32Length; - } while (pstrElement->u8Tag == ASN1_NULL); - } - - return u16ElemLength; -} - -uint16 ASN1_Read(tstrAsn1Context *pstrAsn1Cxt, uint32 u32ReadLength, uint8 *pu8ReadBuffer) -{ - uint16 u16Read = 0; - - if (pstrAsn1Cxt != NULL) { - uint16 u16RemLen = pstrAsn1Cxt->u16BuffLen - (uint16)(pstrAsn1Cxt->pu8Data - pstrAsn1Cxt->pu8Buff); - - u16Read = (uint16)((u32ReadLength <= u16RemLen) ? u32ReadLength : u16RemLen); - - if (pu8ReadBuffer != NULL) { - m2m_memcpy(pu8ReadBuffer, pstrAsn1Cxt->pu8Data, u16Read); - } - - pstrAsn1Cxt->pu8Data += u16Read; - } - - return u16Read; -} - -uint16 ASN1_ReadReference(tstrAsn1Context *pstrAsn1Cxt, uint32 u32ReadLength, uint8 **ppu8ReadBuffer) -{ - uint16 u16Read = 0; - - if (pstrAsn1Cxt != NULL) { - uint16 u16RemLen = pstrAsn1Cxt->u16BuffLen - (uint16)(pstrAsn1Cxt->pu8Data - pstrAsn1Cxt->pu8Buff); - - u16Read = (uint16)((u32ReadLength <= u16RemLen) ? u32ReadLength : u16RemLen); - - if (ppu8ReadBuffer != NULL) { - *ppu8ReadBuffer = pstrAsn1Cxt->pu8Data; - } - - pstrAsn1Cxt->pu8Data += u16Read; - } - - return u16Read; -} diff --git a/src/winc1500/src/hash.c b/src/winc1500/src/hash.c deleted file mode 100644 index b6fb9a8d2..000000000 --- a/src/winc1500/src/hash.c +++ /dev/null @@ -1,527 +0,0 @@ -/** - * - * \file - * - * \brief Hash Functions. - * - * Copyright (c) 2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -#include "root_cert/x509/hash.h" - -#define SHA_SHR(x, n) ((x & 0xFFFFFFFF) >> n) -#define SHA_SHL(x, n) ((x & 0xFFFFFFFF) << n) -#define SHA_ROTR(x, n) (SHA_SHR(x, n) | SHA_SHL(x, (32 - n))) -#define SHA_ROTL(x, n) (SHA_SHL(x, n) | SHA_SHR(x, (32 - n))) - -/* MD5 specific defines. */ -#define F(x, y, z) (((x) & (y)) | (~(x) & (z))) -#define G(x, y, z) (((x) & (z)) | ((y) & ~(z))) -#define H(x, y, z) ((x) ^ (y) ^ (z)) -#define I(x, y, z) ((y) ^ ((x) | ~(z))) - -#define MD5_INERMEDIATE(A, B, C, D, W, K, S) \ - { \ - W += A + K; \ - W = B + SHA_ROTL(W, S); \ - A = D; \ - D = C; \ - C = B; \ - B = W; \ - } - -/* SHA1 specific defines. */ -#define SHA1_CH(x, y, z) (((x) & (y)) | ((~(x)) & (z))) -#define SHA1_MAJ(x, y, z) (((x) & (y)) | ((x) & (z)) | ((y) & (z))) -#define SHA_PARITY(x, y, z) ((x) ^ (y) ^ (z)) -#define SHA1_INERMEDIATE(A, B, C, D, E, W, K) \ - { \ - W += SHA_ROTL(A, 5) + E + K; \ - E = D; \ - D = C; \ - C = SHA_ROTL(B, 30); \ - B = A; \ - A = W; \ - } - -#define SHA_PAD_BYTE 0x80 - -/* SHA256 specific defines. */ -#define SHA256_SMALL_SIGMA0(x) (SHA_ROTR(x, 7) ^ SHA_ROTR(x, 18) ^ SHA_SHR(x, 3)) -#define SHA256_SMALL_SIGMA1(x) (SHA_ROTR(x, 17) ^ SHA_ROTR(x, 19) ^ SHA_SHR(x, 10)) -#define SHA256_CAP_SIGMA0(x) (SHA_ROTR(x, 2) ^ SHA_ROTR(x, 13) ^ SHA_ROTR(x, 22)) -#define SHA256_CAP_SIGMA1(x) (SHA_ROTR(x, 6) ^ SHA_ROTR(x, 11) ^ SHA_ROTR(x, 25)) -#define SHA256_MAJ(x, y, z) ((x & y) | (z & (x | y))) -#define SHA256_CH(x, y, z) (z ^ (x & (y ^ z))) - -static void MD5ProcessBlock(uint32 *pu32Md5State, const uint8 *pu8MessageBlock) -{ - const uint32 T[] = { - 0xD76AA478, 0xE8C7B756, 0x242070DB, 0xC1BDCEEE, 0xF57C0FAF, 0x4787C62A, 0xA8304613, 0xFD469501, - 0x698098D8, 0x8B44F7AF, 0xFFFF5BB1, 0x895CD7BE, 0x6B901122, 0xFD987193, 0xA679438E, 0x49B40821, - 0xF61E2562, 0xC040B340, 0x265E5A51, 0xE9B6C7AA, 0xD62F105D, 0x02441453, 0xD8A1E681, 0xE7D3FBC8, - 0x21E1CDE6, 0xC33707D6, 0xF4D50D87, 0x455A14ED, 0xA9E3E905, 0xFCEFA3F8, 0x676F02D9, 0x8D2A4C8A, - 0xFFFA3942, 0x8771F681, 0x6D9D6122, 0xFDE5380C, 0xA4BEEA44, 0x4BDECFA9, 0xF6BB4B60, 0xBEBFBC70, - 0x289B7EC6, 0xEAA127FA, 0xD4EF3085, 0x04881D05, 0xD9D4D039, 0xE6DB99E5, 0x1FA27CF8, 0xC4AC5665, - 0xF4292244, 0x432AFF97, 0xAB9423A7, 0xFC93A039, 0x655B59C3, 0x8F0CCC92, 0xFFEFF47D, 0x85845DD1, - 0x6FA87E4F, 0xFE2CE6E0, 0xA3014314, 0x4E0811A1, 0xF7537E82, 0xBD3AF235, 0x2AD7D2BB, 0xEB86D391 - }; - uint8 S[] = { - 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, 7, 12, 17, 22, - 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, 5, 9, 14, 20, - 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, 4, 11, 16, 23, - 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21, 6, 10, 15, 21 - }; - uint32 A, B, C, D; - uint32 W = 0; - uint32 X[16]; - uint8 u8Idx, u8Count; - - A = pu32Md5State[0]; - B = pu32Md5State[1]; - C = pu32Md5State[2]; - D = pu32Md5State[3]; - - memcpy(X, pu8MessageBlock, 64); - - for (u8Idx = 0; u8Idx < 16; u8Idx++) { - W = F(B, C, D) + X[u8Idx]; - MD5_INERMEDIATE(A, B, C, D, W, T[u8Idx], S[u8Idx]); - } - - for (u8Idx = 16, u8Count = 1; u8Idx < 32; u8Idx++, u8Count += 5) { - W = G(B, C, D) + X[u8Count & 0x0F]; - MD5_INERMEDIATE(A, B, C, D, W, T[u8Idx], S[u8Idx]); - } - - for (u8Idx = 32, u8Count = 5; u8Idx < 48; u8Idx++, u8Count += 3) { - W = H(B, C, D) + X[u8Count & 0x0F]; - MD5_INERMEDIATE(A, B, C, D, W, T[u8Idx], S[u8Idx]); - } - - for (u8Idx = 48, u8Count = 0; u8Idx < 64; u8Idx++, u8Count += 7) { - W = I(B, C, D) + X[u8Count & 0x0F]; - MD5_INERMEDIATE(A, B, C, D, W, T[u8Idx], S[u8Idx]); - } - - pu32Md5State[0] += A; - pu32Md5State[1] += B; - pu32Md5State[2] += C; - pu32Md5State[3] += D; -} - -static void SHA1ProcessBlock(uint32 *pu32Sha1State, const uint8 *pu8MessageBlock) -{ - /* Constants defined in FIPS-180-2, section 4.2.1 */ - const uint32 K[4] = { - 0x5A827999, - 0x6ED9EBA1, - 0x8F1BBCDC, - 0xCA62C1D6 - }; - int t; /* Loop counter */ - uint32 W[80]; /* Word sequence */ - uint32 A, B, C, D, E; /* Word buffers */ - - /* Initialize the first 16 words in the array W. */ - for (t = 0; t < 16; t++) { - W[t] = GETU32(pu8MessageBlock, (t * 4)); - } - - for (t = 16; t < 80; t++) { - W[t] = SHA_ROTL((W[t - 3] ^ W[t - 8] ^ W[t - 14] ^ W[t - 16]), 1); - } - - A = pu32Sha1State[0]; - B = pu32Sha1State[1]; - C = pu32Sha1State[2]; - D = pu32Sha1State[3]; - E = pu32Sha1State[4]; - - for (t = 0; t < 20; t++) { - W[t] += SHA1_CH(B, C, D); - SHA1_INERMEDIATE(A, B, C, D, E, W[t], K[0]) - } - - for (t = 20; t < 40; t++) { - W[t] += SHA_PARITY(B, C, D); - SHA1_INERMEDIATE(A, B, C, D, E, W[t], K[1]) - } - - for (t = 40; t < 60; t++) { - W[t] += SHA1_MAJ(B, C, D); - SHA1_INERMEDIATE(A, B, C, D, E, W[t], K[2]) - } - - for (t = 60; t < 80; t++) { - W[t] += SHA_PARITY(B, C, D); - SHA1_INERMEDIATE(A, B, C, D, E, W[t], K[3]) - } - - pu32Sha1State[0] += A; - pu32Sha1State[1] += B; - pu32Sha1State[2] += C; - pu32Sha1State[3] += D; - pu32Sha1State[4] += E; -} - -static void SHA256ProcessBlock(uint32 *pu32Sha256State, const uint8 *pu8Data) -{ - /* Hardcoded when using for loop unrolling. */ - /* Constants defined in SHA-256. */ - const uint32 K[] = { - 0x428a2f98, 0x71374491, 0xb5c0fbcf, 0xe9b5dba5, 0x3956c25b, 0x59f111f1, 0x923f82a4, 0xab1c5ed5, - 0xd807aa98, 0x12835b01, 0x243185be, 0x550c7dc3, 0x72be5d74, 0x80deb1fe, 0x9bdc06a7, 0xc19bf174, - 0xe49b69c1, 0xefbe4786, 0x0fc19dc6, 0x240ca1cc, 0x2de92c6f, 0x4a7484aa, 0x5cb0a9dc, 0x76f988da, - 0x983e5152, 0xa831c66d, 0xb00327c8, 0xbf597fc7, 0xc6e00bf3, 0xd5a79147, 0x06ca6351, 0x14292967, - 0x27b70a85, 0x2e1b2138, 0x4d2c6dfc, 0x53380d13, 0x650a7354, 0x766a0abb, 0x81c2c92e, 0x92722c85, - 0xa2bfe8a1, 0xa81a664b, 0xc24b8b70, 0xc76c51a3, 0xd192e819, 0xd6990624, 0xf40e3585, 0x106aa070, - 0x19a4c116, 0x1e376c08, 0x2748774c, 0x34b0bcb5, 0x391c0cb3, 0x4ed8aa4a, 0x5b9cca4f, 0x682e6ff3, - 0x748f82ee, 0x78a5636f, 0x84c87814, 0x8cc70208, 0x90befffa, 0xa4506ceb, 0xbef9a3f7, 0xc67178f2 - }; - - uint32 t; /* Loop counter */ - uint32 temp1, temp2; /* Temporary word value */ - uint32 W[64]; /* Word sequence */ - uint32 A, B, C, D, E, F, G, H; /* Word buffers */ - - A = pu32Sha256State[0]; - B = pu32Sha256State[1]; - C = pu32Sha256State[2]; - D = pu32Sha256State[3]; - E = pu32Sha256State[4]; - F = pu32Sha256State[5]; - G = pu32Sha256State[6]; - H = pu32Sha256State[7]; - - /* Initialize the first 16 words in the array W */ - for (t = 16; (t--) != 0;) { - W[t] = pu8Data[t * 4] << 24; - W[t] |= pu8Data[t * 4 + 1] << 16; - W[t] |= pu8Data[t * 4 + 2] << 8; - W[t] |= pu8Data[t * 4 + 3]; - } - - for (t = 16; t < 64; t++) { - W[t] = SHA256_SMALL_SIGMA1(W[t - 2]) + W[t - 7] + - SHA256_SMALL_SIGMA0(W[t - 15]) + W[t - 16]; - } - - for (t = 0; t < 64; t++) { - temp1 = H + SHA256_CAP_SIGMA1(E) + SHA256_CH(E, F, G) + K[t] + W[t]; - temp2 = SHA256_CAP_SIGMA0(A) + SHA256_MAJ(A, B, C); - - H = G; - G = F; - F = E; - E = D + temp1; - D = C; - C = B; - B = A; - A = temp1 + temp2; - } - - pu32Sha256State[0] += A; - pu32Sha256State[1] += B; - pu32Sha256State[2] += C; - pu32Sha256State[3] += D; - pu32Sha256State[4] += E; - pu32Sha256State[5] += F; - pu32Sha256State[6] += G; - pu32Sha256State[7] += H; -} - -static void Sha_HashUpdate(tstrHashContext *pstrHashCxt, uint8 *pu8Data, uint32 u32DataLength) -{ - if ((pstrHashCxt != NULL) && (pu8Data != NULL) && (u32DataLength != 0)) { - if (pstrHashCxt->fpHash != NULL) { - uint32 u32ResidualBytes; - uint32 u32NBlocks; - uint32 u32Offset; - uint32 u32BlockCount; - - /* Get the remaining bytes from the previous update (if the length is not block alligned). */ - u32ResidualBytes = pstrHashCxt->u32TotalLength % pstrHashCxt->u8BlockSize; - - /* Update the total data length. */ - pstrHashCxt->u32TotalLength += u32DataLength; - - if (u32ResidualBytes != 0) { - if ((u32ResidualBytes + u32DataLength) >= pstrHashCxt->u8BlockSize) { - u32Offset = pstrHashCxt->u8BlockSize - u32ResidualBytes; - memcpy(&pstrHashCxt->au8CurrentBlock[u32ResidualBytes], pu8Data, u32Offset); - pu8Data += u32Offset; - u32DataLength -= u32Offset; - pstrHashCxt->fpHash(pstrHashCxt->au32HashState, pstrHashCxt->au8CurrentBlock); - } else { - memcpy(&pstrHashCxt->au8CurrentBlock[u32ResidualBytes], pu8Data, u32DataLength); - u32DataLength = 0; - } - } - - /* Get the number of HASH BLOCKs and the residual bytes. */ - u32NBlocks = u32DataLength / pstrHashCxt->u8BlockSize; - u32ResidualBytes = u32DataLength % pstrHashCxt->u8BlockSize; - for (u32BlockCount = 0; u32BlockCount < u32NBlocks; u32BlockCount++) { - pstrHashCxt->fpHash(pstrHashCxt->au32HashState, pu8Data); - pu8Data += pstrHashCxt->u8BlockSize; - } - - if (u32ResidualBytes != 0) { - memcpy(pstrHashCxt->au8CurrentBlock, pu8Data, u32ResidualBytes); - } - } - } -} - -static void Sha_HashFinish(tstrHashContext *pstrHashCxt, uint8 *pu8LengthPadding) -{ - if (pstrHashCxt != NULL) { - if (pstrHashCxt->fpHash != NULL) { - uint32 u32Offset; - uint32 u32PaddingLength; - - /* Calculate the offset of the last data byte in the current block. */ - u32Offset = pstrHashCxt->u32TotalLength % pstrHashCxt->u8BlockSize; - - /* Add the padding byte 0x80. */ - pstrHashCxt->au8CurrentBlock[u32Offset++] = SHA_PAD_BYTE; - - /* Calculate the required padding to complete one Hash Block Size. */ - u32PaddingLength = pstrHashCxt->u8BlockSize - u32Offset; - memset(&pstrHashCxt->au8CurrentBlock[u32Offset], 0, u32PaddingLength); - - /* If the padding count is not enough to hold 64-bit representation */ - /* of the total input message length, one padding block is required. */ - if (u32PaddingLength < 8) { - pstrHashCxt->fpHash(pstrHashCxt->au32HashState, pstrHashCxt->au8CurrentBlock); - memset(pstrHashCxt->au8CurrentBlock, 0, pstrHashCxt->u8BlockSize); - } - - memcpy(&pstrHashCxt->au8CurrentBlock[pstrHashCxt->u8BlockSize - 8], pu8LengthPadding, 8); - pstrHashCxt->fpHash(pstrHashCxt->au32HashState, pstrHashCxt->au8CurrentBlock); - } - } -} - -void SHA1_Hash(tstrHashContext *pstrSha1Context, uint8 u8Flags, uint8 *pu8Data, uint32 u32DataLength, uint8 *pu8Digest) { - if (pstrSha1Context != NULL) { - /* SHA1 HASH INITIALIZATION. */ - if (u8Flags & SHA_FLAGS_INIT) { - /* Initialize the Hash Context. */ - memset(pstrSha1Context, 0, sizeof(tstrHashContext)); - - /* Define SHA1 Specific parameters. */ - pstrSha1Context->fpHash = SHA1ProcessBlock; - pstrSha1Context->u8BlockSize = SHA_BLOCK_SIZE; - pstrSha1Context->u8DigestSize = SHA1_DIGEST_SIZE; - - /* Set the Hash state to the initial value (specified by the standard). */ - pstrSha1Context->au32HashState[0] = 0x67452301; - pstrSha1Context->au32HashState[1] = 0xEFCDAB89; - pstrSha1Context->au32HashState[2] = 0x98BADCFE; - pstrSha1Context->au32HashState[3] = 0x10325476; - pstrSha1Context->au32HashState[4] = 0xC3D2E1F0; - } - - /* SHA1 HASH UPDATE. */ - if ((u8Flags & SHA_FLAGS_UPDATE) && (pu8Data != NULL)) { - Sha_HashUpdate(pstrSha1Context, pu8Data, u32DataLength); - } - - /* SHA1 HASH FINISH. */ - if (u8Flags & SHA_FLAGS_FINISH) { - uint8 au8Tmp[8]; - - /* Pack the length at the end of the padding block. */ - PUTU32(pstrSha1Context->u32TotalLength >> 29, au8Tmp, 0); - PUTU32(pstrSha1Context->u32TotalLength << 3, au8Tmp, 4); - Sha_HashFinish(pstrSha1Context, au8Tmp); - - /* Compute digest. */ - PUTU32(pstrSha1Context->au32HashState[0], pu8Digest, 0); - PUTU32(pstrSha1Context->au32HashState[1], pu8Digest, 4); - PUTU32(pstrSha1Context->au32HashState[2], pu8Digest, 8); - PUTU32(pstrSha1Context->au32HashState[3], pu8Digest, 12); - PUTU32(pstrSha1Context->au32HashState[4], pu8Digest, 16); - } - } -} - -void SHA256_Hash(tstrHashContext *pstrSha256Context, uint8 u8Flags, uint8 *pu8Data, uint32 u32DataLength, uint8 *pu8Digest) -{ - if (pstrSha256Context != NULL) { - /* SHA256 HASH INITIALIZATION. */ - if (u8Flags & SHA_FLAGS_INIT) { - /* Initialize the Hash Context. */ - memset(pstrSha256Context, 0, sizeof(tstrHashContext)); - - /* Define SHA256 specific parameters. */ - pstrSha256Context->fpHash = SHA256ProcessBlock; - pstrSha256Context->u8BlockSize = SHA_BLOCK_SIZE; - pstrSha256Context->u8DigestSize = SHA256_DIGEST_SIZE; - - /* Set the Hash state to the initial value (specified by the standard). */ - pstrSha256Context->au32HashState[0] = 0x6A09E667; - pstrSha256Context->au32HashState[1] = 0xBB67AE85; - pstrSha256Context->au32HashState[2] = 0x3C6EF372; - pstrSha256Context->au32HashState[3] = 0xA54FF53A; - pstrSha256Context->au32HashState[4] = 0x510E527F; - pstrSha256Context->au32HashState[5] = 0x9B05688C; - pstrSha256Context->au32HashState[6] = 0x1F83D9AB; - pstrSha256Context->au32HashState[7] = 0x5BE0CD19; - } - - /* SHA256 HASH UPDATE. */ - if ((u8Flags & SHA_FLAGS_UPDATE) && (pu8Data != NULL)) { - Sha_HashUpdate(pstrSha256Context, pu8Data, u32DataLength); - } - - /* SHA256 HASH FINISH. */ - if ((u8Flags & SHA_FLAGS_FINISH) && (pu8Digest != NULL)) { - uint8 au8Tmp[8]; - - /* Pack the length at the end of the padding block. */ - PUTU32(pstrSha256Context->u32TotalLength >> 29, au8Tmp, 0); - PUTU32(pstrSha256Context->u32TotalLength << 3, au8Tmp, 4); - Sha_HashFinish(pstrSha256Context, au8Tmp); - - /* Compute digest. */ - PUTU32(pstrSha256Context->au32HashState[0], pu8Digest, 0); - PUTU32(pstrSha256Context->au32HashState[1], pu8Digest, 4); - PUTU32(pstrSha256Context->au32HashState[2], pu8Digest, 8); - PUTU32(pstrSha256Context->au32HashState[3], pu8Digest, 12); - PUTU32(pstrSha256Context->au32HashState[4], pu8Digest, 16); - PUTU32(pstrSha256Context->au32HashState[5], pu8Digest, 20); - PUTU32(pstrSha256Context->au32HashState[6], pu8Digest, 24); - PUTU32(pstrSha256Context->au32HashState[7], pu8Digest, 28); - } - } -} - -void MD5_Hash( tstrHashContext *pstrMD5Context, uint8 u8Flags, uint8 *pu8Data, uint32 u32DataLength, uint8 *pu8Digest) -{ - if (pstrMD5Context != NULL) { - /* SHA256 HASH INITIALIZATION. */ - if (u8Flags & 1) { - /* Initialize the Hash Context. */ - memset(pstrMD5Context, 0, sizeof(tstrHashContext)); - - /* Define SHA256 specific parameters. */ - pstrMD5Context->fpHash = MD5ProcessBlock; - pstrMD5Context->u8BlockSize = 64; - pstrMD5Context->u8DigestSize = 16; - - pstrMD5Context->au32HashState[0] = 0x67452301; - pstrMD5Context->au32HashState[1] = 0xEFCDAB89; - pstrMD5Context->au32HashState[2] = 0x98BADCFE; - pstrMD5Context->au32HashState[3] = 0x10325476; - } - - /* SHA256 HASH UPDATE. */ - if ((u8Flags & 2) && (pu8Data != NULL)) { - Sha_HashUpdate(pstrMD5Context, pu8Data, u32DataLength); - } - - /* SHA256 HASH FINISH. */ - if ((u8Flags & 4) && (pu8Digest != NULL)) { - uint8 au8Tmp[8] = {0}; - uint8 u8Idx, u8ByteIdx = 0; - uint32 u32LengthBits = pstrMD5Context->u32TotalLength << 3; - - /* Pack the length at the end of the padding block. */ - au8Tmp[0] = BYTE_0(u32LengthBits); - au8Tmp[1] = BYTE_1(u32LengthBits); - au8Tmp[2] = BYTE_2(u32LengthBits); - au8Tmp[3] = BYTE_3(u32LengthBits); - - Sha_HashFinish(pstrMD5Context, au8Tmp); - - /* Compute digest. */ - for (u8Idx = 0; u8Idx < (MD5_DIGEST_SIZE / 4); u8Idx++) { - pu8Digest[u8ByteIdx++] = BYTE_0(pstrMD5Context->au32HashState[u8Idx]); - pu8Digest[u8ByteIdx++] = BYTE_1(pstrMD5Context->au32HashState[u8Idx]); - pu8Digest[u8ByteIdx++] = BYTE_2(pstrMD5Context->au32HashState[u8Idx]); - pu8Digest[u8ByteIdx++] = BYTE_3(pstrMD5Context->au32HashState[u8Idx]); - } - } - } -} - -/** - * \brief Perform the HMAC operation on a given vector of data streams. - */ -void HMAC_Vector(tpfHash fpHash, uint8 *pu8Key, uint32 u32KeyLength, tstrBuffer *pstrInData, uint8 u8NumInputs, uint8 *pu8Out) -{ - if ((pu8Key != NULL) && (pstrInData != NULL) && (pu8Out != NULL) && (fpHash != NULL)) { - tstrHashContext strHashContext; - uint32 i; - uint8 au8TmpBuffer[SHA_BLOCK_SIZE]; - uint8 au8TmpHash[SHA_MAX_DIGEST_SIZE]; - uint8 au8TmpKey[SHA_MAX_DIGEST_SIZE]; - - /* HMAC INIT. */ - /* Adjust the key size. */ - if (u32KeyLength > SHA_BLOCK_SIZE) { - fpHash(&strHashContext, SHA_FLAGS_FULL_HASH, pu8Key, u32KeyLength, pu8Key); - u32KeyLength = strHashContext.u8DigestSize; - pu8Key = au8TmpKey; - } - - memset(au8TmpBuffer, 0x36, SHA_BLOCK_SIZE); - for (i = 0; i < u32KeyLength; i++) { - au8TmpBuffer[i] ^= pu8Key[i]; - } - - /* Start hashing. */ - fpHash(&strHashContext, SHA_FLAGS_INIT | SHA_FLAGS_UPDATE, au8TmpBuffer, SHA_BLOCK_SIZE, NULL); - - /* HMAC UPDATE. */ - for (i = 0; i < u8NumInputs; i++) { - fpHash(&strHashContext, SHA_FLAGS_UPDATE, pstrInData[i].pu8Data, pstrInData[i].u16BufferSize, NULL); - } - - fpHash(&strHashContext, SHA_FLAGS_FINISH, NULL, 0, au8TmpHash); - - /* HMAC Finalize. */ - memset(au8TmpBuffer, 0x5C, SHA_BLOCK_SIZE); - for (i = 0; i < u32KeyLength; i++) { - au8TmpBuffer[i] ^= pu8Key[i]; - } - - fpHash(&strHashContext, SHA_FLAGS_INIT | SHA_FLAGS_UPDATE, au8TmpBuffer, SHA_BLOCK_SIZE, NULL); - fpHash(&strHashContext, SHA_FLAGS_UPDATE | SHA_FLAGS_FINISH, au8TmpHash, strHashContext.u8DigestSize, pu8Out); - } -} diff --git a/src/winc1500/src/programmer.c b/src/winc1500/src/programmer.c index 8b5d753e8..5b3b73a79 100644 --- a/src/winc1500/src/programmer.c +++ b/src/winc1500/src/programmer.c @@ -3,16 +3,11 @@ #include "fb_alloc.h" #include "programmer/programmer.h" -#include "root_cert/root_setup.h" #include "spi_flash/include/spi_flash_map.h" -#define FW_PATH "/firmware/bin/m2m_aio_3a0.bin" -#define FW_DUMP_PATH "/firmware/bin/fw_dump.bin" -#define CERT_DIGI_PATH "/firmware/cert/DigiCert_Root.cer" -#define CERT_DIGISHA2_PATH "/firmware/cert/DigiCertSHA2_Root.cer" -#define CERT_GEOTRUST_PATH "/firmware/cert/GeoTrustGlobalCA_Root.cer" -#define CERT_RADIUS_PATH "/firmware/cert/Radius_Root.cer" -#define CERT_VERISIGN_PATH "/firmware/cert/VeriSign_Root.cer" +// TODO pass file paths +#define FW_PATH "/firmware/m2m_aio_3a0.bin" +#define FW_DUMP_PATH "/firmware/fw_dump.bin" #define MIN(a,b) \ ({ __typeof__ (a) _a = (a); \ @@ -166,79 +161,3 @@ error: f_close(&fp); return ret; } - -static int burn_certificate(const char *cert, const char *path) -{ - FIL fp; - int ret = M2M_ERR_FAIL; - // This is big enough for the max certificate - char *buf = fb_alloc(FLASH_SECTOR_SZ); - - if (f_open(&fp, path, FA_READ|FA_OPEN_EXISTING) != FR_OK) { - goto error; - } - - UINT bytes_out=0; - UINT bytes = f_size(&fp); - - // Read root certificate - if (f_read(&fp, buf, bytes, &bytes_out) != FR_OK || bytes_out != bytes) { - printf("burn_certificate: file read error!\n"); - goto error; - } - - // Write root certificate to the WINC1500 memory. - ret = WriteRootCertificate(cert, buf, bytes); - -error: - fb_free(); - f_close(&fp); - return ret; - -} - -/** - * Program root certificates to WINC1500 memory. - * - * return: M2M_SUCCESS on success, error code otherwise. - */ -int burn_certificates() -{ - const char *root_certs[][2] = { - {"DigiCert_Root", CERT_DIGI_PATH }, - {"DigiCertSHA2_Root", CERT_DIGISHA2_PATH}, - {"GeoTrustGlobalCA_Root", CERT_GEOTRUST_PATH}, - {"Radius_Root", CERT_RADIUS_PATH }, - {"VeriSign_Root", CERT_VERISIGN_PATH}, - {0, 0} - }; - - int ret=M2M_SUCCESS; - for (int i=0; ret==M2M_SUCCESS && root_certs[i][0]; i++) { - ret = burn_certificate(root_certs[i][0], root_certs[i][1]); - } - - return ret; -} - -/** - * Verify WINC1500 certificates - * return M2M_SUCCESS on success, error code otherwise. - */ -int verify_certificates(void) -{ - int ret = M2M_ERR_FAIL; - uint8_t *flash_buf = fb_alloc(FLASH_SECTOR_SZ); - - /* Dump entire root certificate memory region. */ - if (programmer_read_cert_image(flash_buf) != M2M_SUCCESS) { - printf("verify_certificate: read access failed on certificate section!\r\n"); - goto error; - } - - ret = M2M_SUCCESS; - -error: - fb_free(); - return ret; -} diff --git a/src/winc1500/src/root_setup.c b/src/winc1500/src/root_setup.c deleted file mode 100644 index 47554c9cc..000000000 --- a/src/winc1500/src/root_setup.c +++ /dev/null @@ -1,253 +0,0 @@ -/** - * - * \file - * - * \brief Root Certificate Setup. - * - * Copyright (c) 2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -#include "fb_alloc.h" -#include "root_cert/x509/x509_cert.h" -#include "root_cert/root_setup.h" -#include "programmer/programmer_apis.h" - -//#define ENABLE_VERIFICATION - -#define WORD_ALIGN(val) (((val) & 0x03) ? ((val) + 4 - ((val) & 0x03)) : (val)) - -#define ROOT_CERT_FLASH_START_PATTERN_LENGTH 16 - -#define ROOT_CERT_FLASH_START_PATTERN \ - { \ - 0x01, 0xF1, 0x02, 0xF2, 0x03, 0xF3, 0x04, 0xF4, \ - 0x05, 0xF5, 0x06, 0xF6, 0x07, 0xF7, 0x08, 0xF8 \ - } - -/*!< A Pattern is stored at the start of the root certificate flash area - * in order to identify if the flash is written before or not. - */ - -typedef struct { - uint8 au8StartPattern[ROOT_CERT_FLASH_START_PATTERN_LENGTH]; - uint32 u32nCerts; -} tstrRootCertFlashHeader; - -typedef struct { - uint8 au8SHA1NameHash[SHA1_DIGEST_SIZE]; - uint16 u16NSize; - uint16 u16ESize; - uint8 au8ValidityStartDate[20]; - uint8 au8ValidityExpDate[20]; -} tstrRootCertEntryHeader; - -#ifdef ENABLE_VERIFICATION -static uint8 gau8Verify[M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE]; -#endif - -/** - * \brief Parse and validate certificate. - * - * \return M2M_SUCCESS on success, error code otherwise. - */ -static int GetRootCertificate(uint8 *pcRootCertFileData, uint32 u32FileSize, tstrX509Cert *pstrX509, uint8 **ppu8CertificateBuffer) -{ - sint8 ret = -1; - - /* Decode the certificate. */ - if (X509Cert_Decode(pcRootCertFileData, u32FileSize, pstrX509, 1) == X509_SUCCESS) { - printf(">Root certificate verified OK.\n"); - *ppu8CertificateBuffer = pcRootCertFileData; - ret = 0; - } else { - ret = -1; - } - - return ret; -} - -/** - * \brief Update the root certificate list. - * - * \return M2M_SUCCESS on success, error code otherwise. - */ -static sint8 UpdateRootList(tstrX509Cert *pstrRootCert, uint8 *gau8RootCertMem) -{ - uint32 u32Idx; - uint8 bIncrement = 0; - uint32 u32nStoredCerts = 0; - uint8 au8StartPattern[] = ROOT_CERT_FLASH_START_PATTERN; - tstrRootCertFlashHeader *pstrRootFlashHdr; - tstrRootCertEntryHeader *pstrEntryHDR; - uint16 u16BufferOffset; - uint16 u16WriteSize; - tstrRSAPublicKey *pstrKey; - - pstrKey = &pstrRootCert->strPubKey.strRSAKey; - pstrRootFlashHdr = (tstrRootCertFlashHeader *)((void *)gau8RootCertMem); - u16BufferOffset = sizeof(tstrRootCertFlashHeader); - u16WriteSize = pstrKey->u16ESize + pstrKey->u16NSize + sizeof(tstrRootCertEntryHeader); - - /* Check if the flash has been written before. */ - if (!memcmp(au8StartPattern, pstrRootFlashHdr->au8StartPattern, ROOT_CERT_FLASH_START_PATTERN_LENGTH)) { - u32nStoredCerts = pstrRootFlashHdr->u32nCerts; - bIncrement = 1; - - for (u32Idx = 0; u32Idx < u32nStoredCerts; u32Idx++) { - pstrEntryHDR = (tstrRootCertEntryHeader *)((void *)&gau8RootCertMem[u16BufferOffset]); - - /* Check for match (equivalent NameSHA1). */ - if (!memcmp(pstrRootCert->strSubject.au8NameSHA1, pstrEntryHDR->au8SHA1NameHash, SHA1_DIGEST_SIZE)) { - /* The current entry will be overwritten. */ - bIncrement = 0; - break; - } - - u16BufferOffset += sizeof(tstrRootCertEntryHeader) + WORD_ALIGN(pstrEntryHDR->u16NSize + pstrEntryHDR->u16ESize); - } - } else { - pstrRootFlashHdr->u32nCerts = 0; - memcpy(pstrRootFlashHdr->au8StartPattern, au8StartPattern, ROOT_CERT_FLASH_START_PATTERN_LENGTH); - bIncrement = 1; - } - - if (bIncrement) { - /* A new certificate is to be inserted into the flash. */ - /* Increment the number of stored Certificates. */ - if (u16BufferOffset + u16WriteSize > M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE) { - printf("(ERROR) Root Certificate Flash is Full\n"); - return -1; - } - - pstrRootFlashHdr->u32nCerts++; - } - - /* Write Root Certificate to flash. The entry is ordered as follows: - - SHA1_DIGEST_SIZE --> NameSHA1 of the Root certificate. - - uint16 --> N_SIZE (Byte count for the RSA modulus N). - - uint16 --> E_SIZE (Byte count for the RSA public exponent E). - - START_DATE --> Start date of the root certificate(20 bytes). - - EXPIRATION_DATE --> Expiration date of the root certificate(20 bytes). - - N_SIZE --> RSA Modulus N. - - E_SIZE --> RSA Public exponent. - */ - - pstrEntryHDR = (tstrRootCertEntryHeader *)((void *)&gau8RootCertMem[u16BufferOffset]); - - /* NameSHA1 */ - memcpy(pstrEntryHDR->au8SHA1NameHash, pstrRootCert->strSubject.au8NameSHA1, SHA1_DIGEST_SIZE); - - /* N_SIZE */ - pstrEntryHDR->u16NSize = pstrKey->u16NSize; - - /* E_SIZE */ - pstrEntryHDR->u16ESize = pstrKey->u16ESize; - - /* Start Date */ - memcpy(pstrEntryHDR->au8ValidityStartDate, pstrRootCert->strStartDate.au8Time, 20); - - /* Expiration Date */ - memcpy(pstrEntryHDR->au8ValidityExpDate, pstrRootCert->strExpiryDate.au8Time, 20); - u16BufferOffset += sizeof(tstrRootCertEntryHeader); - - /* N */ - memcpy(&gau8RootCertMem[u16BufferOffset], pstrKey->pu8N, pstrKey->u16NSize); - - /* E */ - memcpy(&gau8RootCertMem[u16BufferOffset + pstrKey->u16NSize], pstrKey->pu8E, pstrKey->u16ESize); - - return 0; -} - -/** - * \brief Write root certificate to flash. - * - * \return M2M_SUCCESS on success, error code otherwise. - */ -int WriteRootCertificate(const char *filename, char *pcRootCertFileData, uint32 u32FileSize) -{ - uint8 *pu8CertBuffer; - tstrX509Cert strX509Root; -#ifdef ENABLE_VERIFICATION - uint32 u32Idx; -#endif - int ret = -1; - - uint8 *gau8RootCertMem = fb_alloc(M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE); - - /* Read Certificate File. */ - if (GetRootCertificate((uint8 *)pcRootCertFileData, u32FileSize, &strX509Root, &pu8CertBuffer) == 0) { - programmer_read_cert_image(gau8RootCertMem); - - if (UpdateRootList(&strX509Root, gau8RootCertMem) == 0) { - /* Erase memory. */ - ret = programmer_erase_cert_image(); - if (M2M_SUCCESS != ret) { - goto END; - } - - nm_bsp_sleep(50); - - /* Write. */ - printf(">Writing the certificate to SPI flash...\r\n"); - ret = programmer_write_cert_image(gau8RootCertMem); - if (M2M_SUCCESS != ret) { - goto END; - } - - printf("Done\r\n"); - -#ifdef ENABLE_VERIFICATION - /* Verification. */ - memset(gau8Verify, 0, M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE); - programmer_read_cert_image(gau8Verify); - - for (u32Idx = 0; u32Idx < M2M_TLS_FLASH_ROOTCERT_CACHE_SIZE; u32Idx++) { - if (gau8RootCertMem[u32Idx] != gau8Verify[u32Idx]) { - printf("ERROR verification failed at %u\n", u32Idx); - ret = -1; - break; - } - } -#endif - } - } else { - printf("\r\n>>>Invalid root certificate %s\n", filename); - } - -END: - fb_free(); - return ret; -} diff --git a/src/winc1500/src/x509_cert.c b/src/winc1500/src/x509_cert.c deleted file mode 100644 index c39f691f1..000000000 --- a/src/winc1500/src/x509_cert.c +++ /dev/null @@ -1,895 +0,0 @@ -/** - * - * \file - * - * \brief X509 Certificate Functions. - * - * Copyright (c) 2015 Atmel Corporation. All rights reserved. - * - * \asf_license_start - * - * \page License - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions are met: - * - * 1. Redistributions of source code must retain the above copyright notice, - * this list of conditions and the following disclaimer. - * - * 2. Redistributions in binary form must reproduce the above copyright notice, - * this list of conditions and the following disclaimer in the documentation - * and/or other materials provided with the distribution. - * - * 3. The name of Atmel may not be used to endorse or promote products derived - * from this software without specific prior written permission. - * - * THIS SOFTWARE IS PROVIDED BY ATMEL "AS IS" AND ANY EXPRESS OR IMPLIED - * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT ARE - * EXPRESSLY AND SPECIFICALLY DISCLAIMED. IN NO EVENT SHALL ATMEL BE LIABLE FOR - * ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, - * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN - * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE - * POSSIBILITY OF SUCH DAMAGE. - * - * \asf_license_stop - * - */ - -#include "root_cert/x509/x509_cert.h" -#include "root_cert/x509/asn1.h" - -/* X509 SUPPORTED VERSIONS. */ -#define X509_VER_1 0 -#define X509_VER_2 1 -#define X509_VER_3 2 - -/* X509 CERTIFICATE PARSING STATES. */ - -#define CERT_VERSION_PENDING 0 -#define CERT_SERIAL_PENDING 1 -#define CERT_SIGNATURE_PENDING 2 -#define CERT_ISSUER_PENDING 3 -#define CERT_VALIDITY_PENDING 4 -#define CERT_SUBJECT_PENDING 5 -#define CERT_SUBECTKEYINFO_PENDING 6 -#define CERT_EXTENSIONS_PENDING 7 -#define CERT_PARSING_DONE 8 - -/* X509 ENCODED FIELD IDs. */ - -#define X509_VERSION 0xA0 - -/*!< - * Identifier of the version field in the X.509 certificate - * encoding. It is given in the ASN.1 syntax as - * [0] EXPLICIT - * Context-Specific class (10) | constructed (1) | 00000 - */ - -#define X509_SERIAL_NO ASN1_INTEGER - -/*!< - * Identifier for the certificate serial num ber element. - */ - -#define X509_SIGNATURE ASN1_SEQUENCE - -/*!< - * Identifier for the Signature algorithm ID element. - */ - -#define X509_ISSUER ASN1_SEQUENCE - -/*!< - * Identifier for the certificate ISSUER element. - */ - -#define X509_VALIDITY ASN1_SEQUENCE - -/*!< - * Identifier for the certificate validity interval element. - */ - -#define X509_SUBJECT ASN1_SEQUENCE - -/*!< - * Identifier for the certificate SUBJECT information element. - */ - -#define X509_SUBJECT_KEY_INFO ASN1_SEQUENCE - -/*!< - * Identifier for the publick key information element. - */ - -#define X509_ISSUER_UNIQUE_ID 0x81 - -/*!< - * Encoded value for the issuerUniqueID tag. It is defined as - * [1] IMPLICIT BIT STRING - * Context-Specific class (10) | primitive (0) | 00001 - */ - -#define X509_SUBJECT_UNIQUE_ID 0x82 - -/*!< - * Encoded value for the subjectUniqueID tag. It is defined as - * [2] IMPLICIT BIT STRING - * Context-Specific class (10) | primitive (0) | 00010 - */ - -#define X509_EXTENSIONS_ID 0xA3 - -/*!< - * Encoded value for the issuerUniqueID tag. It is defined as - * [3] EXPLICIT - * Context-Specific class (10) | constructed (1) | 00011 - */ - -/* NAME ATTRIBUTE IDs. */ - -#define ID_AT 85, 0x04, -#define ID_AT_COMMONNAME {ID_AT 3 } -#define ID_AT_SERIALNUMBER {ID_AT 5 } -#define ID_AT_COUNTRYNAME {ID_AT 6 } -#define ID_AT_ORGANIZATIONNAME {ID_AT 10} -#define ID_AT_ORGANIZATIONALUNITNAME {ID_AT 11} - -#define X520_COMMON_NAME 1 -#define X520_ORG_UNIT 2 -#define X520_ORG 3 - -/* CERTIFICATE EXTENSION IDs. */ - -#define ID_CE 85, 29, -#define ID_CE_AUTHORITY_KEY_ID {ID_CE 35} -#define ID_CE_SUBJECT_KEY_ID {ID_CE 14} - -/* SIGNATURE ALGORITHM IDs. */ - -#define PKCS_1 0x2A, 0x86, 0x48, 0x86, 0xF7, 0x0d, 0x01, 0x01, -/* 1.2.840.113549.1.1 */ - -#define RSA_ENCRYPTION {PKCS_1 1} /* 1.2.840.113549.1.1 */ -#define MD5_WITH_RSA_ENCRYPTION {PKCS_1 4} /* 1.2.840.113549.1.1.4 */ -#define SHA1_WITH_RSA_ENCRYPTION {PKCS_1 5} /* 1.2.840.113549.1.1.5 */ -#define SHA256_WITH_RSA_ENCRYPTION {PKCS_1 11} /* 1.2.840.113549.1.1.11 */ -#define SHA384_WITH_RSA_ENCRYPTION {PKCS_1 12} /* 1.2.840.113549.1.1.12 */ -#define SHA512_WITH_RSA_ENCRYPTION {PKCS_1 13} /* 1.2.840.113549.1.1.13 */ - -typedef struct { - uint8 u8Type; - uint8 *pu8Name; - uint8 u8Length; -} tstrX520DistinguishedName; - -sint8 M2M_GetTimeOfDay(tstrSystemTime *pstrSysTime); -uint8 Cert_DecodeAlgID(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size); -sint8 Cert_DecodeDistinguishedName(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrX520DistinguishedName *pstrDN); -sint8 Cert_DecodeX520Name(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrX520Name *pstrName); -sint8 Cert_DecodeRSAPubKey(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32KeySize, tstrRSAPublicKey *pstrRsaPublicKey); -sint8 Cert_DecodeSubjectPubKey(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrPublicKey *pstrPubKey); -sint8 Cert_DecodeValidity(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrX509Time *pstrNotBefore, tstrX509Time *pstrNotAfter); -sint8 Cert_DecodeTBSCertificate(tstrAsn1Context *pstrX509Asn1Cxt, uint16 u16CertSize, tstrX509Cert *pstrCert); -sint8 Cert_DecodeTime(uint8 *pu8Time, tstrSystemTime *pstrTime); -sint8 Cert_CompareTime(tstrSystemTime *pstrT1, tstrSystemTime *pstrT2); -uint8 X509Cert_IsValid(void *pvX509); - -sint8 M2M_GetTimeOfDay(tstrSystemTime *pstrSysTime) -{ -#ifdef WIN32 - SYSTEMTIME winTime; - GetSystemTime(&winTime); - pstrSysTime->u16Year = (uint16)winTime.wYear; - pstrSysTime->u8Month = (uint8)winTime.wMonth; - pstrSysTime->u8Day = (uint8)winTime.wDay; - pstrSysTime->u8Hour = (uint8)winTime.wHour; - pstrSysTime->u8Minute = (uint8)winTime.wMinute; - pstrSysTime->u8Second = (uint8)winTime.wSecond; -#else - pstrSysTime->u16Year = (uint16)(2015); - pstrSysTime->u8Month = (uint8)8; - pstrSysTime->u8Day = (uint8)6; - pstrSysTime->u8Hour = (uint8)9; - pstrSysTime->u8Minute = (uint8)39; - pstrSysTime->u8Second = (uint8)10; -#endif - - return M2M_SUCCESS; -} - -/** - * \brief Perform decoding to the data type "AlgorithmIdentifier". - */ -uint8 Cert_DecodeAlgID(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size) -{ - /* - * AlgorithmIdentifier ::= SEQUENCE { - * algorithm OBJECT IDENTIFIER, - * parameters NULL - * } - */ - - const uint8 gau8SecAlgorithms[][16] = { - RSA_ENCRYPTION, - MD5_WITH_RSA_ENCRYPTION, - SHA1_WITH_RSA_ENCRYPTION, - SHA256_WITH_RSA_ENCRYPTION, - SHA384_WITH_RSA_ENCRYPTION, - SHA512_WITH_RSA_ENCRYPTION - }; - #define X509_NUM_SUPPORTED_SEC_ALGORITHMS (sizeof(gau8SecAlgorithms) / sizeof(gau8SecAlgorithms[0])) - - uint8 u8Alg = X509_ALG_NULL; - - if (pstrX509Asn1Cxt != NULL) { - tstrAsn1Element strElem; - - /* Initialize a decoding object for this SEQUENCE. */ - ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem); - if (strElem.u8Tag == ASN1_OBJECT_IDENTIFIER) { - if (strElem.u32Length <= 16) { - uint8 u8Idx; - uint8 au8AlgID[16]; - ASN1_Read(pstrX509Asn1Cxt, strElem.u32Length, au8AlgID); - for (u8Idx = 0; u8Idx < X509_NUM_SUPPORTED_SEC_ALGORITHMS; u8Idx++) { - if (!m2m_memcmp(au8AlgID, (uint8 *)gau8SecAlgorithms[u8Idx], strElem.u32Length)) { - u8Alg = u8Idx + 1; - break; - } - } - } - } - } - - return u8Alg; -} - -sint8 Cert_DecodeDistinguishedName(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrX520DistinguishedName *pstrDN) -{ - sint8 s8Ret = X509_FAIL; - - if ((pstrX509Asn1Cxt != NULL) && (pstrDN != NULL)) { - tstrAsn1Element strElem; - - ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem); - if (strElem.u8Tag == ASN1_OBJECT_IDENTIFIER) { - uint8 au8CmnNameID[4] = ID_AT_COMMONNAME; - uint8 au8TempID[16]; - - pstrDN->u8Type = 0; - ASN1_Read(pstrX509Asn1Cxt, strElem.u32Length, au8TempID); - if (!m2m_memcmp(au8CmnNameID, au8TempID, strElem.u32Length)) { - pstrDN->u8Type = X520_COMMON_NAME; - } - - if (ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem) != ASN1_FAIL) { - pstrDN->u8Length = (uint8)strElem.u32Length; - ASN1_ReadReference(pstrX509Asn1Cxt, strElem.u32Length, &pstrDN->pu8Name); - s8Ret = X509_SUCCESS; - } - } - } - - return s8Ret; -} - -sint8 Cert_DecodeX520Name(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrX520Name *pstrName) -{ - /* - * Name ::= CHOICE { -- only one possibility for now -- - * rdnSequence RDNSequence - * } - * - * RDNSequence ::= SEQUENCE OF RelativeDistinguishedName - * - * RelativeDistinguishedName ::= - * SET SIZE (1..MAX) OF AttributeTypeAndValue - * - * AttributeTypeAndValue ::= SEQUENCE { - * type AttributeType, - * value AttributeValue - * } - * - * AttributeType ::= OBJECT IDENTIFIER - * AttributeValue ::= ANY -- DEFINED BY AttributeType - * - * DirectoryString ::= CHOICE { - * teletexString TeletexString (SIZE (1..MAX)), - * printableString PrintableString (SIZE (1..MAX)), - * universalString UniversalString (SIZE (1..MAX)), - * utf8String UTF8String (SIZE (1..MAX)), - * bmpString BMPString (SIZE (1..MAX)) - * } - */ - sint8 s8Ret = X509_SUCCESS; - - if ((pstrX509Asn1Cxt != NULL) && (pstrName != NULL)) { - tstrAsn1Element strSetElem, strSeqElem; - tstrX520DistinguishedName strDN; - tstrSha1Context strSha1Cxt; - uint16 u16Offset = 0; - - SHA1_INIT(&strSha1Cxt); - - /* RelativeDistinguishedName. */ - while (u16Offset < u32Size) { - u16Offset += ASN1_GetNextElement(pstrX509Asn1Cxt, &strSetElem); - if (strSetElem.u8Tag == ASN1_SET) { - ASN1_GetNextElement(pstrX509Asn1Cxt, &strSeqElem); - if (strSeqElem.u8Tag != ASN1_SEQUENCE) { - s8Ret = X509_FAIL; - break; - } - - if (Cert_DecodeDistinguishedName(pstrX509Asn1Cxt, strSeqElem.u32Length, &strDN) != X509_SUCCESS) { - s8Ret = X509_FAIL; - break; - } - - if (strDN.u8Type == X520_COMMON_NAME) { - m2m_memcpy((uint8 *)pstrName->acCmnName, strDN.pu8Name, strDN.u8Length); - pstrName->acCmnName[strDN.u8Length] = '\0'; - } else if (strDN.u8Type == X520_ORG_UNIT) { - if (pstrName->acOrgUnit[0] == 0) { - m2m_memcpy((uint8 *)pstrName->acOrgUnit, strDN.pu8Name, strDN.u8Length); - pstrName->acOrgUnit[strDN.u8Length] = '\0'; - } - } else if (strDN.u8Type == X520_ORG) { - m2m_memcpy((uint8 *)pstrName->acOrg, strDN.pu8Name, strDN.u8Length); - pstrName->acOrg[strDN.u8Length] = '\0'; - } - - SHA1_UPDATE(&strSha1Cxt, strDN.pu8Name, strDN.u8Length); - } else { - break; - } - } - SHA1_FINISH(&strSha1Cxt, pstrName->au8NameSHA1); - } - - return s8Ret; -} - -sint8 Cert_DecodeRSAPubKey(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32KeySize, tstrRSAPublicKey *pstrRsaPublicKey) -{ - /* - * RSAPublicKey ::= SEQUENCE { - * modulus INTEGER, -- n - * publicExponent INTEGER -- e - * } - */ - sint8 s8Ret = X509_FAIL; - if ((pstrX509Asn1Cxt != NULL) && (pstrRsaPublicKey != NULL)) { - tstrAsn1Element strElem; - - ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem); - if (strElem.u8Tag == ASN1_SEQUENCE) { - ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem); - if (strElem.u8Tag == ASN1_INTEGER) { - ASN1_ReadReference(pstrX509Asn1Cxt, strElem.u32Length, &pstrRsaPublicKey->pu8N); - while (*pstrRsaPublicKey->pu8N == 0) { - pstrRsaPublicKey->pu8N++; - strElem.u32Length--; - } - pstrRsaPublicKey->u16NSize = (uint16)strElem.u32Length; - - ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem); - if (strElem.u8Tag == ASN1_INTEGER) { - ASN1_ReadReference(pstrX509Asn1Cxt, strElem.u32Length, &pstrRsaPublicKey->pu8E); - while (*pstrRsaPublicKey->pu8E == 0) { - pstrRsaPublicKey->pu8E++; - strElem.u32Length--; - } - pstrRsaPublicKey->u16ESize = (uint16)strElem.u32Length; - s8Ret = X509_SUCCESS; - } - } - } - } - - return s8Ret; -} - -sint8 Cert_DecodeSubjectPubKey(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrPublicKey *pstrPubKey) -{ - /* - * SubjectPublicKeyInfo ::= SEQUENCE { - * algorithm AlgorithmIdentifier, - * subjectPublicKey BIT STRING - * } - */ - sint8 s8Ret = X509_SUCCESS; - - if ((pstrX509Asn1Cxt != NULL) && (pstrPubKey != NULL)) { - tstrAsn1Element strElem; - uint8 u8PubKeyAlg = 0; - uint16 u16Offset = 0; - - while (u16Offset < u32Size) { - u16Offset += ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem); - if (strElem.u8Tag == ASN1_SEQUENCE) { - u8PubKeyAlg = Cert_DecodeAlgID(pstrX509Asn1Cxt, strElem.u32Length); - } else if (strElem.u8Tag == ASN1_BIT_STRING) { - if (u8PubKeyAlg != X509_PUB_RSA) { - s8Ret = X509_FAIL; - break; - } - - pstrPubKey->enuType = PUBKEY_ALG_RSA; - ASN1_Read(pstrX509Asn1Cxt, 1, NULL); - s8Ret = Cert_DecodeRSAPubKey(pstrX509Asn1Cxt, strElem.u32Length - 1, &pstrPubKey->strRSAKey); - break; - } - } - } - - return s8Ret; -} - -sint8 Cert_DecodeValidity(tstrAsn1Context *pstrX509Asn1Cxt, uint32 u32Size, tstrX509Time *pstrNotBefore, tstrX509Time *pstrNotAfter) -{ - /* - * Validity ::= SEQUENCE { - * notBefore Time, - * notAfter Time - * } - */ - sint8 s8Ret = X509_FAIL; - - if ((pstrX509Asn1Cxt != 0) && (pstrNotAfter != NULL) && (pstrNotBefore != NULL)) { - tstrAsn1Element strElem; - - if (ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem) != ASN1_INVALID) { - /* Start time. */ - ASN1_Read(pstrX509Asn1Cxt, strElem.u32Length, pstrNotBefore->au8Time); - pstrNotBefore->au8Time[strElem.u32Length] = '\0'; - - if (ASN1_GetNextElement(pstrX509Asn1Cxt, &strElem) != ASN1_INVALID) { - /* End time. */ - ASN1_Read(pstrX509Asn1Cxt, strElem.u32Length, pstrNotAfter->au8Time); - pstrNotAfter->au8Time[strElem.u32Length] = '\0'; - s8Ret = X509_SUCCESS; - } - } - } - - return s8Ret; -} - -sint8 Cert_DecodeTBSCertificate(tstrAsn1Context *pstrX509Asn1Cxt, uint16 u16CertSize, tstrX509Cert *pstrCert) -{ - /* - * TBSCertificate ::= SEQUENCE { - * version [0] - * Version DEFAULT v1, - * serialNumber CertificateSerialNumber, - * signature AlgorithmIdentifier, - * issuer Name, - * validity Validity, - * subject Name, - * subjectPublicKeyInfo SubjectPublicKeyInfo, - * issuerUniqueID [1] IMPLICIT UniqueIdentifier OPTIONAL, If present, version MUST be v2 or v3 - * subjectUniqueID [2] IMPLICIT UniqueIdentifier OPTIONAL, If present, version MUST be v2 or v3 - * extensions [3] Extensions OPTIONAL If present, version MUST be v3 - * } - * - */ - sint8 s8Ret = X509_SUCCESS; - - if ((pstrX509Asn1Cxt != NULL) && (pstrCert != NULL)) { - uint16 u16ReadOffset = 0; - tstrAsn1Element strElement; - uint8 u8CertState = CERT_VERSION_PENDING; - - /* Loop on the elements of the certificate until finishing. */ - while (u16ReadOffset < u16CertSize) { - u16ReadOffset += ASN1_GetNextElement(pstrX509Asn1Cxt, &strElement); - switch (u8CertState) { - case CERT_VERSION_PENDING: - - /* Version. */ - if (strElement.u8Tag == X509_VERSION) { - /* The encoding of version is on the form A0 03 02 01 ver. */ - if (strElement.u32Length < 3) { - s8Ret = X509_FAIL; - } - - ASN1_Read(pstrX509Asn1Cxt, 2, NULL); - ASN1_Read(pstrX509Asn1Cxt, 1, &pstrCert->u8Version); - u8CertState = CERT_SERIAL_PENDING; - } else if (strElement.u8Tag == X509_SERIAL_NO) { - /* The certificate version number is absent from the certificate. */ - /* It will be set to the default value Version 1.0. */ - pstrCert->u8Version = X509_VER_1; - - /* The first field is the serial number. */ - if (strElement.u32Length > X509_SERIAL_NO_MAX_LENGTH) { - strElement.u32Length = X509_SERIAL_NO_MAX_LENGTH; - } - - pstrCert->u8SerialNumberLength = (uint8)strElement.u32Length; - ASN1_Read(pstrX509Asn1Cxt, strElement.u32Length, pstrCert->au8SerialNo); - u8CertState = CERT_SIGNATURE_PENDING; - } - - break; - - case CERT_SERIAL_PENDING: - - /* SerialNumber. */ - if (strElement.u8Tag == X509_SERIAL_NO) { - /* The first field is the serial number. */ - if (strElement.u32Length > X509_SERIAL_NO_MAX_LENGTH) { - strElement.u32Length = X509_SERIAL_NO_MAX_LENGTH; - } - - pstrCert->u8SerialNumberLength = (uint8)strElement.u32Length; - ASN1_Read(pstrX509Asn1Cxt, strElement.u32Length, pstrCert->au8SerialNo); - u8CertState = CERT_SIGNATURE_PENDING; - } - - break; - - case CERT_SIGNATURE_PENDING: - - /* Signature. */ - if (strElement.u8Tag == X509_SIGNATURE) { - pstrCert->u8SignAlg = Cert_DecodeAlgID(pstrX509Asn1Cxt, strElement.u32Length); - u8CertState = CERT_ISSUER_PENDING; - } - - break; - - case CERT_ISSUER_PENDING: - - /* Issuer. */ - if (strElement.u8Tag == X509_ISSUER) { - Cert_DecodeX520Name(pstrX509Asn1Cxt, strElement.u32Length, &pstrCert->strIssuer); - u8CertState = CERT_VALIDITY_PENDING; - } - - break; - - case CERT_VALIDITY_PENDING: - - /* Validity. */ - if (strElement.u8Tag == X509_VALIDITY) { - Cert_DecodeValidity(pstrX509Asn1Cxt, strElement.u32Length, - &pstrCert->strStartDate, &pstrCert->strExpiryDate); - u8CertState = CERT_SUBJECT_PENDING; - } - - break; - - case CERT_SUBJECT_PENDING: - - /* Subject. */ - if (strElement.u8Tag == X509_SUBJECT) { - Cert_DecodeX520Name(pstrX509Asn1Cxt, strElement.u32Length, &pstrCert->strSubject); - u8CertState = CERT_SUBECTKEYINFO_PENDING; - } - - break; - - case CERT_SUBECTKEYINFO_PENDING: - - /* SubjectPublicKeyInfo. */ - if (strElement.u8Tag == X509_SUBJECT_KEY_INFO) { - Cert_DecodeSubjectPubKey(pstrX509Asn1Cxt, strElement.u32Length, &pstrCert->strPubKey); - u8CertState = CERT_EXTENSIONS_PENDING; - } - - break; - - case CERT_EXTENSIONS_PENDING: - ASN1_Read(pstrX509Asn1Cxt, strElement.u32Length, NULL); - break; - } - } - } - - return s8Ret; -} - -sint8 X509Cert_Decode(uint8 *pu8X509Buffer, uint32 u32CertSize, tstrX509Cert *pstrCert, uint8 bDumpX509) -{ - /* - * - * Certificate ::= SEQUENCE { - * tbsCertificate TBSCertificate, - * signatureAlgorithm AlgorithmIdentifier, - * signature BIT STRING } - * - */ - sint8 s8Ret = X509_FAIL; - - if ((pu8X509Buffer != NULL) && (pstrCert != NULL)) { - tstrAsn1Context strX509ASN1Cxt; - tstrAsn1Element strElement; - uint8 u8SignAlgorithm = X509_ALG_NULL; - - /* Initialize the certificate structure. */ - m2m_memset((uint8 *)pstrCert, 0, sizeof(tstrX509Cert)); - - /* Initialize the ASN1 Decoding operation. */ - strX509ASN1Cxt.pu8Buff = pu8X509Buffer; - strX509ASN1Cxt.pu8Data = pu8X509Buffer; - - ASN1_GetNextElement(&strX509ASN1Cxt, &strElement); - if ((strElement.u8Tag == ASN1_SEQUENCE) && (strElement.u32Length < u32CertSize)) { - /* Copy the TBS certificate. It shall be used later to calculate the certificate HASH. */ - pstrCert->pu8TBSCert = strX509ASN1Cxt.pu8Data; - - /* tbsCertificate. */ - pstrCert->u16TBSCertSize = ASN1_GetNextElement(&strX509ASN1Cxt, &strElement); - if (strElement.u8Tag == ASN1_SEQUENCE) { - if (Cert_DecodeTBSCertificate(&strX509ASN1Cxt, (uint16)strElement.u32Length, pstrCert) == 0) { - /* signatureAlgorithm. */ - ASN1_GetNextElement(&strX509ASN1Cxt, &strElement); - if (strElement.u8Tag == ASN1_SEQUENCE) { - /* Check if the signatureAlgorithm ID obtained in this element matches */ - /* the signature field of the TBS Certificate. */ - u8SignAlgorithm = Cert_DecodeAlgID(&strX509ASN1Cxt, strElement.u32Length); - if (u8SignAlgorithm == pstrCert->u8SignAlg) { - /* signature. */ - ASN1_GetNextElement(&strX509ASN1Cxt, &strElement); - if (strElement.u8Tag == ASN1_BIT_STRING) { - /* Store the obtained signature. */ - pstrCert->strSignature.u16BufferSize = (uint16)strElement.u32Length - 1; - - /* Jump one byte. */ - ASN1_Read(&strX509ASN1Cxt, 1, NULL); - - /* Get the signature value. */ - ASN1_ReadReference(&strX509ASN1Cxt, pstrCert->strSignature.u16BufferSize, - &pstrCert->strSignature.pu8Data); - - /* Dump the certificate contents. */ - if (bDumpX509) { - X509_CERT_DUMP(pstrCert); - } - - s8Ret = X509_SUCCESS; - } - } - } - } - } - } - } - - return s8Ret; -} - -#define X509_UTC_TIME_LENGTH 0x0D - -/*!< - * The UTC time for the X.509 encoding takes the format - * YYMMDDHHMMSSZ. Each digit is BCD encoded as ASCII digit. - */ - -#define X509_GENERALIZED_TIME_LENGTH 0x0F - -/*!< - * The UTC time for the X.509 encoding takes the format - * YYYYMMDDHHMMSSZ. Each digit is BCD encoded as ASCII digit. - */ - -#define GET_VAL(BUF, OFFSET) (((BUF)[OFFSET] * 10) + ((BUF)[OFFSET + 1])) - -sint8 Cert_DecodeTime(uint8 *pu8Time, tstrSystemTime *pstrTime) -{ - sint8 s8Ret = X509_FAIL; - - if (pu8Time != NULL) { - uint8 u8TimeLength = (uint8)strlen((char *)pu8Time); - uint8 au8Time[20]; - uint8 u8Idx; - - memcpy(au8Time, pu8Time, 20); - - if ((u8TimeLength >= X509_UTC_TIME_LENGTH) && (u8TimeLength <= X509_GENERALIZED_TIME_LENGTH)) { - if (au8Time[u8TimeLength - 1] == 'Z') { - for (u8Idx = 0; u8Idx < (u8TimeLength - 1); u8Idx++) { - au8Time[u8Idx] -= '0'; - } - - if (u8TimeLength == X509_UTC_TIME_LENGTH) { - pstrTime->u16Year = (au8Time[0] * 10) + au8Time[1]; - pstrTime->u16Year += (pstrTime->u16Year < 50 ? 2000 : 1900); - u8Idx = 2; - } else { - pstrTime->u16Year = (au8Time[0] * 1000) + (au8Time[1] * 100) + (au8Time[2] * 10) + au8Time[3]; - u8Idx = 4; - } - - pstrTime->u8Month = GET_VAL(au8Time, u8Idx); - u8Idx += 2; - - pstrTime->u8Day = GET_VAL(au8Time, u8Idx); - u8Idx += 2; - - pstrTime->u8Hour = GET_VAL(au8Time, u8Idx); - u8Idx += 2; - - pstrTime->u8Minute = GET_VAL(au8Time, u8Idx); - u8Idx += 2; - - pstrTime->u8Second = GET_VAL(au8Time, u8Idx); - - s8Ret = X509_SUCCESS; - } - } - } - - return s8Ret; -} - -sint8 Cert_CompareTime(tstrSystemTime *pstrT1, tstrSystemTime *pstrT2) -{ - sint8 s8Cmp = 1; - - if ((pstrT1 != NULL) && (pstrT2 != NULL)) { - /* YEAR. */ - if (pstrT1->u16Year == pstrT2->u16Year) { - /* MONTH. */ - if (pstrT1->u8Month == pstrT2->u8Month) { - /* DAY */ - if (pstrT1->u8Day == pstrT2->u8Day) { - s8Cmp = pstrT1->u8Hour - pstrT2->u8Hour; - } else { - s8Cmp = pstrT1->u8Day - pstrT2->u8Day; - } - } else { - s8Cmp = pstrT1->u8Month - pstrT2->u8Month; - } - } else { - s8Cmp = pstrT1->u16Year - pstrT2->u16Year; - } - } - - return s8Cmp; -} - -uint8 X509Cert_IsValid(void *pvX509) -{ - tstrX509Cert *pstrX509 = (tstrX509Cert *)pvX509; - uint8 u8Status = X509_STATUS_VALID; - - if (pstrX509 != NULL) { - tstrSystemTime strExpirationDate = {0}; - - if (Cert_DecodeTime(pstrX509->strExpiryDate.au8Time, &strExpirationDate) == X509_SUCCESS) { - M2M_DBG("Expiration Date\n\t%d-%02d-%02d %02d:%02d:%02d\n", - strExpirationDate.u16Year, strExpirationDate.u8Month, strExpirationDate.u8Day, - strExpirationDate.u8Hour, strExpirationDate.u8Minute, strExpirationDate.u8Second); - - if (strExpirationDate.u16Year != 9999) { -#ifdef WIN32 - if (M2M_GetTimeOfDay(&strSystemTime) == M2M_SUCCESS) { - if (Cert_CompareTime(&strExpirationDate, &strSystemTime) <= 0) { - u8Status = X509_STATUS_EXPIRED; - } - } -#endif - } - } else { - u8Status = X509_STATUS_DECODE_ERR; - } - } else { - u8Status = X509_STATUS_DECODE_ERR; - } - - return u8Status; -} - -void X509Cert_Dump(void *pvCert) -{ - tstrX509Cert *pstrCert = (tstrX509Cert *)pvCert; - if (pstrCert != NULL) { -#define X509_DUMP_ENABLE -#ifdef X509_DUMP_ENABLE - uint32 i; - tstrSystemTime strTime = {0}; - - printf("\r\n"); - printf("*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=\r\n"); - printf(" ROOT CERTIFICATE \r\n"); - printf("*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=\r\n"); - - printf("VERSION %u\r\n", pstrCert->u8Version + 1); - printf("SERIAL NO "); - for (i = 0; i < pstrCert->u8SerialNumberLength; i++) { - printf("%02X ", pstrCert->au8SerialNo[i]); - } - printf("\r\n"); - - printf("SIGNATURE ALGORITHM "); - if (pstrCert->u8SignAlg == X509_SIGN_MD5RSA) { - printf("md5WithRsaEncryption"); - } else if (pstrCert->u8SignAlg == X509_SIGN_SHA1RSA) { - printf("shaWithRsaEncryption"); - } else if (pstrCert->u8SignAlg == X509_SIGN_SHA256RSA) { - printf("sha256WithRsaEncryption"); - } else if (pstrCert->u8SignAlg == X509_SIGN_SHA384RSA) { - printf("sha384WithRsaEncryption"); - } else if (pstrCert->u8SignAlg == X509_SIGN_SHA512RSA) { - printf("sha512WithRsaEncryption"); - } - - printf("\r\n"); - - printf("ISSUER "); - if (strlen(pstrCert->strIssuer.acCmnName) != 0) { - printf("%s", pstrCert->strIssuer.acCmnName); - } - - printf("\r\n"); - - printf("SUBJECT "); - if (strlen(pstrCert->strSubject.acCmnName) != 0) { - printf("%s", pstrCert->strSubject.acCmnName); - } - - printf("\r\n"); - - printf("VALIDITY\n"); - printf(" Not Before : "); - Cert_DecodeTime(pstrCert->strStartDate.au8Time, &strTime); - printf("%d-%02d-%02d %02d:%02d:%02d\r\n", - strTime.u16Year, strTime.u8Month, strTime.u8Day, - strTime.u8Hour, strTime.u8Minute, strTime.u8Second); - - printf(" Not After : "); - Cert_DecodeTime(pstrCert->strExpiryDate.au8Time, &strTime); - printf("%d-%02d-%02d %02d:%02d:%02d\r\n", - strTime.u16Year, strTime.u8Month, strTime.u8Day, - strTime.u8Hour, strTime.u8Minute, strTime.u8Second); - - if (pstrCert->strPubKey.enuType == PUBKEY_ALG_RSA) { - printf("PUBLIC KEY "); - printf("RSA\n\n"); - printf("\tModulus"); - for (i = 0; i < pstrCert->strPubKey.strRSAKey.u16NSize; i++) { - if (!(i % 16)) { - printf("\r\n\t\t"); - } - - printf("%02X ", pstrCert->strPubKey.strRSAKey.pu8N[i]); - } - printf("\r\n"); - - printf("\tExponent"); - for (i = 0; i < pstrCert->strPubKey.strRSAKey.u16ESize; i++) { - if (!(i % 16)) { - printf("\r\n\t\t"); - } - - printf("%02X ", pstrCert->strPubKey.strRSAKey.pu8E[i]); - } - } - - printf("\r\n"); - - printf("SIGNATURE"); - for (i = 0; i < pstrCert->strSignature.u16BufferSize; i++) { - if (!(i % 16)) { - printf("\r\n\t"); - } - - printf("%02X ", pstrCert->strSignature.pu8Data[i]); - } - printf("\r\n"); - printf("*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=*=\n"); -#else - M2M_INFO("*=*=* X509 *=*=*\n"); - M2M_INFO("\tSubject <%s>\n", ((strlen(pstrCert->strSubject.acCmnName) != 0) ? pstrCert->strSubject.acCmnName : " ")); - M2M_INFO("\tIssuer <%s>\n", ((strlen(pstrCert->strIssuer.acCmnName) != 0) ? pstrCert->strIssuer.acCmnName : " ")); -#endif - } -}