зеркало из https://github.com/mozilla/gecko-dev.git
Bug 998513 - Test GeneralizedTime encodings in mozilla::pkix. r=keeler.
This commit is contained in:
Родитель
ea5bd3dd98
Коммит
a8ba8291e3
|
@ -305,13 +305,34 @@ TEST_F(pkixder_universal_types_tests, EnumeratedInvalidZeroLength)
|
|||
ASSERT_EQ(SEC_ERROR_BAD_DER, PR_GetError());
|
||||
}
|
||||
|
||||
// TODO: Test all acceptable timestamp formats. Find out what formats
|
||||
// are being used by looking at large collection of certs.
|
||||
////////////////////////////////////////
|
||||
// GeneralizedTime
|
||||
//
|
||||
// From RFC 5280 section 4.1.2.5.2
|
||||
//
|
||||
// For the purposes of this profile, GeneralizedTime values MUST be
|
||||
// expressed in Greenwich Mean Time (Zulu) and MUST include seconds
|
||||
// (i.e., times are YYYYMMDDHHMMSSZ), even where the number of seconds
|
||||
// is zero. GeneralizedTime values MUST NOT include fractional seconds.
|
||||
//
|
||||
// And from from RFC 6960 (OCSP) section 4.2.2.1:
|
||||
//
|
||||
// Responses can contain four times -- thisUpdate, nextUpdate,
|
||||
// producedAt, and revocationTime. The semantics of these fields are
|
||||
// defined in Section 2.4. The format for GeneralizedTime is as
|
||||
// specified in Section 4.1.2.5.2 of [RFC5280].
|
||||
//
|
||||
// So while we can could accept other ASN1 (ITU-T X.680) encodings for
|
||||
// GeneralizedTime we should not accept them, and breaking reading of these
|
||||
// other encodings is actually encouraged.
|
||||
|
||||
// TODO(Bug 1023605) a GeneralizedTimes with a timezone offset are should not
|
||||
// be considered valid
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeOffset)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_OFFSET[] = {
|
||||
0x18,
|
||||
19,
|
||||
0x18, // Generalized Time
|
||||
19, // Length = 19
|
||||
'1', '9', '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', '-',
|
||||
'0', '7', '0', '0'
|
||||
};
|
||||
|
@ -328,27 +349,24 @@ TEST_F(pkixder_universal_types_tests, GeneralizedTimeOffset)
|
|||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeGMT)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_GMT[] = {
|
||||
0x18,
|
||||
15,
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'1', '9', '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0', 'Z'
|
||||
};
|
||||
|
||||
Input input;
|
||||
Result rv1 = input.Init(DER_GENERALIZED_TIME_GMT,
|
||||
sizeof DER_GENERALIZED_TIME_GMT);
|
||||
ASSERT_EQ(Success, rv1);
|
||||
|
||||
ASSERT_EQ(Success, input.Init(DER_GENERALIZED_TIME_GMT,
|
||||
sizeof DER_GENERALIZED_TIME_GMT));
|
||||
PRTime value = 0;
|
||||
Result rv2 = GeneralizedTime(input, value);
|
||||
ASSERT_EQ(Success, rv2);
|
||||
ASSERT_EQ(Success, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(673548340000000, value);
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidZeroLength)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_ZERO_LENGTH[] = {
|
||||
0x18,
|
||||
0x00
|
||||
0x18, // GeneralizedTime
|
||||
0x00 // Length = 0
|
||||
};
|
||||
|
||||
Input input;
|
||||
|
@ -361,6 +379,354 @@ TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidZeroLength)
|
|||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
// A non zulu time should fail
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidLocal)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_LOCAL[] = {
|
||||
0x18, // Generalized Time
|
||||
14, // Length = 14
|
||||
'1', '9', '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', '4', '0'
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_LOCAL,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_LOCAL));
|
||||
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
// A time missing seconds and zulu should fail
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidTruncated)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_TRUNCATED[] = {
|
||||
0x18, // Generalized Time
|
||||
12, // Length = 12
|
||||
'1', '9', '9', '1', '0', '5', '0', '6', '1', '6', '4', '5'
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_TRUNCATED,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_TRUNCATED));
|
||||
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
// TODO(bug 1023605) Generalized Times without seconds should not be
|
||||
// considered valid
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeNoSeconds)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_NO_SECONDS[] = {
|
||||
0x18, // Generalized Time
|
||||
13, // Length = 13
|
||||
'1', '9', '9', '1', '0', '5', '0', '6', '1', '6', '4', '5', 'Z'
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_NO_SECONDS,
|
||||
sizeof DER_GENERALIZED_TIME_NO_SECONDS));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Success, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(673548300000000, value);
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidPrefixedYear)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_PREFIXED_YEAR[] = {
|
||||
0x18, // Generalized Time
|
||||
16, // Length = 16
|
||||
' ', '1', '9', '9', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', 'Z'
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_PREFIXED_YEAR,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_PREFIXED_YEAR));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalid5DigitYear)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_5_DIGIT_YEAR[] = {
|
||||
0x18, // Generalized Time
|
||||
16, // Length = 16
|
||||
'1', '1', '1', '1', '1', '0', '1', '0', '1', '0', '1', '0', '1', '0', '1', 'Z'
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_5_DIGIT_YEAR,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_5_DIGIT_YEAR));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidMonth)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_MONTH[] = {
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'1', '9', '9', '1', //YYYY (1991)
|
||||
'1', '3', //MM 13th month of the year
|
||||
'0', '6', '1', '6', '4', '5', '4', '0', 'Z'
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_MONTH,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_MONTH));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
// TODO(bug 1023437) Generalized times with invalid days for a given month
|
||||
// should be rejected
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidDayFeb)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_DAY_FEB[] = {
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'1', '9', '9', '1', // YYYY 1991
|
||||
'0', '2', // MM (February)
|
||||
'3', '0', // DD (the 30th which does not exist)
|
||||
'1', '6', '4', '5', '4', '0', 'Z'
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_DAY_FEB,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_DAY_FEB));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Success, GeneralizedTime(input, value));
|
||||
// The current invalid returned value is Sat, 02 Mar 1991 16:45:40 GMT
|
||||
ASSERT_EQ(667932340000000, value);
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidDayDec)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_DAY_DEC[] = {
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'1', '9', '9', '1', // YYYY 1991
|
||||
'1', '2', // MM (December)
|
||||
'3', '2', // DD (the 32nd which does not exist)
|
||||
'1', '6', '4', '5', '4', '0', 'Z'
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_DAY_DEC,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_DAY_DEC));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeLeapSecondJune)
|
||||
{
|
||||
// No leap seconds ever (allowing them would be non-trivial).
|
||||
const uint8_t DER_GENERALIZED_TIME_LEAP_SECOND_JUNE[] = {
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'2', '0', '1', '2', '0', '6', '3', '0', // YYYYMMDD (2012-06-30)
|
||||
'2', '3', '5', '9', '6', '0', 'Z' // HHMMSSZ (23:59:60 Zulu)
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_LEAP_SECOND_JUNE,
|
||||
sizeof DER_GENERALIZED_TIME_LEAP_SECOND_JUNE));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidHours)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_HOURS[] = {
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'2', '0', '1', '2', '0', '6', '3', '0', // YYYYMMDD (2012-06-30)
|
||||
'2', '5', '5', '9', '0', '1', 'Z' // HHMMSSZ (!!25!!:59:01 Zulu)
|
||||
};
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_HOURS,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_HOURS));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidMinutes)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_MINUTES[] = {
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'2', '0', '1', '2', '0', '6', '3', '0', // YYYYMMDD (2012-06-30)
|
||||
'2', '3', '6', '0', '5', '9', 'Z' // HHMMSSZ (23:!!!60!!!:01 Zulu)
|
||||
};
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_MINUTES,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_MINUTES));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidSeconds)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_SECONDS[] = {
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'2', '0', '1', '2', '0', '6', '3', '0', // YYYYMMDD (2012-06-30)
|
||||
'2', '3', '5', '9', '6', '1', 'Z' // HHMMSSZ (23:59:!!!!61!!!! Zulu)
|
||||
};
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_SECONDS,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_SECONDS));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidZulu)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_ZULU[] = {
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'2', '0', '1', '2', '0', '6', '3', '0', // YYYYMMDD (2012-06-30)
|
||||
'2', '3', '5', '9', '5', '9', 'z' // HHMMSSZ (23:59:59 !!!z!!!) should be Z
|
||||
};
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_ZULU,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_ZULU));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidExtraData)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_EXTRA_DATA[] = {
|
||||
0x18, // Generalized Time
|
||||
16, // Length = 16
|
||||
'2', '0', '1', '2', '0', '6', '3', '0', // YYYYMMDD (2012-06-30)
|
||||
'2', '3', '5', '9', '5', '9', 'Z', // HHMMSSZ (23:59:59Z)
|
||||
0 // Extra null character
|
||||
};
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_EXTRA_DATA,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_EXTRA_DATA));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidCenturyChar)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_CENTURY_CHAR[] = {
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'X', '9', '9', '1', '1', '2', '0', '6', // YYYYMMDD (X991-12-06)
|
||||
'1', '6', '4', '5', '4', '0', 'Z' // HHMMSSZ (16:45:40Z)
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_CENTURY_CHAR,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_CENTURY_CHAR));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidYearChar)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_YEAR_CHAR[] = {
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'1', '9', '9', 'I', '0', '1', '0', '6', // YYYYMMDD (199I-12-06)
|
||||
'1', '6', '4', '5', '4', '0', 'Z' // HHMMSSZ (16:45:40Z)
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_YEAR_CHAR,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_YEAR_CHAR));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidMonthChar)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_MONTH_CHAR[] = {
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'1', '9', '9', '1', '0', 'I', '0', '6', // YYYYMMDD (1991-0I-06)
|
||||
'1', '6', '4', '5', '4', '0', 'Z' // HHMMSSZ (16:45:40Z)
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_MONTH_CHAR,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_MONTH_CHAR));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidDayChar)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_DAY_CHAR[] = {
|
||||
0x18, // Generalized Time
|
||||
15, // Length = 15
|
||||
'1', '9', '9', '1', '0', '1', '0', 'S', // YYYYMMDD (1991-01-0S)
|
||||
'1', '6', '4', '5', '4', '0', 'Z' // HHMMSSZ (16:45:40Z)
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_DAY_CHAR,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_DAY_CHAR));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, GeneralizedTimeInvalidFractionalSeconds)
|
||||
{
|
||||
const uint8_t DER_GENERALIZED_TIME_INVALID_FRACTIONAL_SECONDS[] = {
|
||||
0x18, // Generalized Time
|
||||
17, // Length = 17
|
||||
'1', '9', '9', '1', '0', '1', '0', '1', // YYYYMMDD (1991-01-01)
|
||||
'1', '6', '4', '5', '4', '0', '.', '3', 'Z' // HHMMSS.FFF (16:45:40.3Z)
|
||||
};
|
||||
|
||||
Input input;
|
||||
ASSERT_EQ(Success,
|
||||
input.Init(DER_GENERALIZED_TIME_INVALID_FRACTIONAL_SECONDS,
|
||||
sizeof DER_GENERALIZED_TIME_INVALID_FRACTIONAL_SECONDS));
|
||||
PRTime value = 0;
|
||||
ASSERT_EQ(Failure, GeneralizedTime(input, value));
|
||||
ASSERT_EQ(SEC_ERROR_INVALID_TIME, PR_GetError());
|
||||
}
|
||||
|
||||
TEST_F(pkixder_universal_types_tests, Integer_0_127)
|
||||
{
|
||||
for (uint8_t i = 0; i <= 127; ++i) {
|
||||
|
|
Загрузка…
Ссылка в новой задаче