* @brief Calculates the final signature based on the following parameters and base16 encodes it. * * signing key = HMAC-SHA256(HMAC-SHA256(HMAC-SHA256(HMAC-SHA256("AWS4" + " ", ), * ), ),"aws4_request") * * @see AWS spec: http://docs.aws.amazon.com/AmazonS3/latest/API/sig-v4-header-based-auth.html * * @param awsSecret AWS secret
| 654 | * @return number of characters written to the output buffer |
| 655 | */ |
| 656 | size_t |
| 657 | getSignature(const char *awsSecret, size_t awsSecretLen, const char *awsRegion, size_t awsRegionLen, const char *awsService, |
| 658 | size_t awsServiceLen, const char *dateTime, size_t dateTimeLen, const char *stringToSign, size_t stringToSignLen, |
| 659 | char *signature, size_t signatureLen) |
| 660 | { |
| 661 | unsigned int dateKeyLen = EVP_MAX_MD_SIZE; |
| 662 | unsigned char dateKey[EVP_MAX_MD_SIZE]; |
| 663 | unsigned int dateRegionKeyLen = EVP_MAX_MD_SIZE; |
| 664 | unsigned char dateRegionKey[EVP_MAX_MD_SIZE]; |
| 665 | unsigned int dateRegionServiceKeyLen = EVP_MAX_MD_SIZE; |
| 666 | unsigned char dateRegionServiceKey[EVP_MAX_MD_SIZE]; |
| 667 | unsigned int signingKeyLen = EVP_MAX_MD_SIZE; |
| 668 | unsigned char signingKey[EVP_MAX_MD_SIZE]; |
| 669 | |
| 670 | size_t keyLen = 4 + awsSecretLen; |
| 671 | char key[keyLen]; |
| 672 | memcpy(key, "AWS4", 4); |
| 673 | memcpy(key + 4, awsSecret, awsSecretLen); |
| 674 | |
| 675 | unsigned int len = signatureLen; |
| 676 | if (HMAC(EVP_sha256(), key, keyLen, (unsigned char *)dateTime, dateTimeLen, dateKey, &dateKeyLen) && |
| 677 | HMAC(EVP_sha256(), dateKey, dateKeyLen, (unsigned char *)awsRegion, awsRegionLen, dateRegionKey, &dateRegionKeyLen) && |
| 678 | HMAC(EVP_sha256(), dateRegionKey, dateRegionKeyLen, (unsigned char *)awsService, awsServiceLen, dateRegionServiceKey, |
| 679 | &dateRegionServiceKeyLen) && |
| 680 | HMAC(EVP_sha256(), dateRegionServiceKey, dateRegionServiceKeyLen, reinterpret_cast<const unsigned char *>("aws4_request"), 12, |
| 681 | signingKey, &signingKeyLen) && |
| 682 | HMAC(EVP_sha256(), signingKey, signingKeyLen, (unsigned char *)stringToSign, stringToSignLen, |
| 683 | reinterpret_cast<unsigned char *>(signature), &len)) { |
| 684 | return len; |
| 685 | } |
| 686 | |
| 687 | return 0; |
| 688 | } |
| 689 | |
| 690 | /** |
| 691 | * @brief formats the time stamp in ISO8601 format: <YYYYMMDDTHHMMSSZ> |