int git_signature_new(git_signature **sig_out, const char *name, const char *email, git_time_t time, int offset) { git_signature *p = NULL; assert(name && email); *sig_out = NULL; if (contains_angle_brackets(name) || contains_angle_brackets(email)) { return signature_error( "Neither `name` nor `email` should contain angle brackets chars."); } p = git__calloc(1, sizeof(git_signature)); GITERR_CHECK_ALLOC(p); p->name = extract_trimmed(name, strlen(name)); GITERR_CHECK_ALLOC(p->name); p->email = extract_trimmed(email, strlen(email)); GITERR_CHECK_ALLOC(p->email); if (p->name[0] == '\0' || p->email[0] == '\0') { git_signature_free(p); return signature_error("Signature cannot have an empty name or email"); } p->when.time = time; p->when.offset = offset; *sig_out = p; return 0; }
static int process_trimming(const char *input, char **storage, const char *input_end, int fail_when_empty) { const char *left, *right; size_t trimmed_input_length; assert(storage); left = skip_leading_spaces(input, input_end); right = skip_trailing_spaces(input, input_end - 1); if (right < left) { if (fail_when_empty) return signature_error("input is either empty of contains only spaces"); right = left - 1; } trimmed_input_length = right - left + 1; *storage = git__malloc(trimmed_input_length + 1); GITERR_CHECK_ALLOC(*storage); memcpy(*storage, left, trimmed_input_length); (*storage)[trimmed_input_length] = 0; return 0; }
int git_signature_new(git_signature **sig_out, const char *name, const char *email, git_time_t time, int offset) { git_signature *p = NULL; assert(name && email); *sig_out = NULL; p = git__calloc(1, sizeof(git_signature)); GITERR_CHECK_ALLOC(p); if (process_trimming(name, &p->name, name + strlen(name), 1) < 0 || process_trimming(email, &p->email, email + strlen(email), 1) < 0) { git_signature_free(p); return -1; } if (contains_angle_brackets(p->email) || contains_angle_brackets(p->name)) { git_signature_free(p); return signature_error("Neither `name` nor `email` should contain angle brackets chars."); } p->when.time = time; p->when.offset = offset; *sig_out = p; return 0; }
SignedMeta::SignedMeta(std::vector<uint8_t> raw_meta, std::vector<uint8_t> signature, const Secret& secret, bool check_signature) : raw_meta_(std::make_shared<std::vector<uint8_t>>(std::move(raw_meta))), signature_(std::make_shared<std::vector<uint8_t>>(std::move(signature))) { if(check_signature) { try { CryptoPP::ECDSA<CryptoPP::ECP, CryptoPP::SHA3_256>::Verifier verifier; CryptoPP::ECP::Point p; verifier.AccessKey().AccessGroupParameters().Initialize(CryptoPP::ASN1::secp256r1()); verifier.AccessKey().AccessGroupParameters().SetPointCompression(true); verifier.AccessKey().GetGroupParameters().GetCurve().DecodePoint(p, secret.get_Public_Key().data(), secret.get_Public_Key().size()); verifier.AccessKey().SetPublicElement(p); if(! verifier.VerifyMessage(raw_meta_->data(), raw_meta_->size(), signature_->data(), signature_->size())) throw signature_error(); }catch(CryptoPP::Exception& e){ throw signature_error(); } } meta_ = std::make_shared<Meta>(*raw_meta_); }
int git_signature__parse(git_signature *sig, const char **buffer_out, const char *buffer_end, const char *header, char ender) { const char *buffer = *buffer_out; const char *email_start, *email_end; memset(sig, 0, sizeof(git_signature)); if ((buffer_end = memchr(buffer, ender, buffer_end - buffer)) == NULL) return signature_error("no newline given"); if (header) { const size_t header_len = strlen(header); if (buffer + header_len >= buffer_end || memcmp(buffer, header, header_len) != 0) return signature_error("expected prefix doesn't match actual"); buffer += header_len; } email_start = git__memrchr(buffer, '<', buffer_end - buffer); email_end = git__memrchr(buffer, '>', buffer_end - buffer); if (!email_start || !email_end || email_end <= email_start) return signature_error("malformed e-mail"); email_start += 1; sig->name = extract_trimmed(buffer, email_start - buffer - 1); sig->email = extract_trimmed(email_start, email_end - email_start); /* Do we even have a time at the end of the signature? */ if (email_end + 2 < buffer_end) { const char *time_start = email_end + 2; const char *time_end; if (git__strtol64(&sig->when.time, time_start, &time_end, 10) < 0) return signature_error("invalid Unix timestamp"); /* do we have a timezone? */ if (time_end + 1 < buffer_end) { int offset, hours, mins; const char *tz_start, *tz_end; tz_start = time_end + 1; if ((tz_start[0] != '-' && tz_start[0] != '+') || git__strtol32(&offset, tz_start + 1, &tz_end, 10) < 0) { //malformed timezone, just assume it's zero offset = 0; } hours = offset / 100; mins = offset % 100; /* * only store timezone if it's not overflowing; * see http://www.worldtimezone.com/faq.html */ if (hours < 14 && mins < 59) { sig->when.offset = (hours * 60) + mins; if (tz_start[0] == '-') sig->when.offset = -sig->when.offset; } } } *buffer_out = buffer_end + 1; return 0; }